|
Blender
V2.59
|
00001 /* 00002 * $Id: mjpeg.c 35249 2011-02-27 20:43:42Z jesterking $ 00003 * 00004 * This is external code. Converts between avi and mpeg/jpeg. 00005 * 00006 * ***** BEGIN GPL LICENSE BLOCK ***** 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00023 * All rights reserved. 00024 * 00025 * The Original Code is: all of this file. 00026 * 00027 * Contributor(s): none yet. 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 * 00031 */ 00032 00038 #include "AVI_avi.h" 00039 #include <stdlib.h> 00040 #include <string.h> 00041 #include "jpeglib.h" 00042 #include "jerror.h" 00043 #include "MEM_guardedalloc.h" 00044 00045 #include "mjpeg.h" 00046 00047 #define PADUP(num, amt) ((num+(amt-1))&~(amt-1)) 00048 00049 static void jpegmemdestmgr_build (j_compress_ptr cinfo, unsigned char *buffer, int bufsize); 00050 static void jpegmemsrcmgr_build (j_decompress_ptr dinfo, unsigned char *buffer, int bufsize); 00051 00052 static int numbytes; 00053 00054 static void add_huff_table (j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) { 00055 if (*htblptr == NULL) 00056 *htblptr = jpeg_alloc_huff_table((j_common_ptr) dinfo); 00057 00058 memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits)); 00059 memcpy((*htblptr)->huffval, val, sizeof((*htblptr)->huffval)); 00060 00061 /* Initialize sent_table FALSE so table will be written to JPEG file. */ 00062 (*htblptr)->sent_table = FALSE; 00063 } 00064 00065 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ 00066 /* IMPORTANT: these are only valid for 8-bit data precision! */ 00067 00068 static void std_huff_tables (j_decompress_ptr dinfo) { 00069 static const UINT8 bits_dc_luminance[17] = 00070 { /* 0-base */ 00071 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; 00072 static const UINT8 val_dc_luminance[] = 00073 { 00074 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 00075 00076 static const UINT8 bits_dc_chrominance[17] = 00077 { /* 0-base */ 00078 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; 00079 static const UINT8 val_dc_chrominance[] = 00080 { 00081 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 00082 00083 static const UINT8 bits_ac_luminance[17] = 00084 { /* 0-base */ 00085 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; 00086 static const UINT8 val_ac_luminance[] = 00087 { 00088 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 00089 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 00090 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 00091 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 00092 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 00093 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 00094 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 00095 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 00096 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 00097 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 00098 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 00099 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 00100 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 00101 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 00102 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 00103 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 00104 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 00105 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 00106 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 00107 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 00108 0xf9, 0xfa }; 00109 static const UINT8 bits_ac_chrominance[17] = 00110 { /* 0-base */ 00111 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; 00112 static const UINT8 val_ac_chrominance[] = 00113 { 00114 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 00115 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 00116 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 00117 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 00118 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 00119 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 00120 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 00121 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 00122 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 00123 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 00124 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 00125 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 00126 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 00127 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 00128 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 00129 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 00130 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 00131 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 00132 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 00133 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 00134 0xf9, 0xfa }; 00135 00136 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0], 00137 bits_dc_luminance, val_dc_luminance); 00138 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0], 00139 bits_ac_luminance, val_ac_luminance); 00140 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1], 00141 bits_dc_chrominance, val_dc_chrominance); 00142 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1], 00143 bits_ac_chrominance, val_ac_chrominance); 00144 } 00145 00146 static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, int bufsize) { 00147 int rowstride; 00148 unsigned int y; 00149 struct jpeg_decompress_struct dinfo; 00150 struct jpeg_error_mgr jerr; 00151 00152 (void)width; /* unused */ 00153 00154 numbytes= 0; 00155 00156 dinfo.err = jpeg_std_error(&jerr); 00157 jpeg_create_decompress(&dinfo); 00158 jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize); 00159 jpeg_read_header(&dinfo, TRUE); 00160 if (dinfo.dc_huff_tbl_ptrs[0] == NULL){ 00161 std_huff_tables(&dinfo); 00162 } 00163 dinfo.out_color_space = JCS_RGB; 00164 dinfo.dct_method = JDCT_IFAST; 00165 00166 jpeg_start_decompress(&dinfo); 00167 00168 rowstride= dinfo.output_width*dinfo.output_components; 00169 for (y= 0; y<dinfo.output_height; y++) { 00170 jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1); 00171 outBuffer += rowstride; 00172 } 00173 jpeg_finish_decompress(&dinfo); 00174 00175 if (dinfo.output_height >= height) return 0; 00176 00177 inBuffer+= numbytes; 00178 jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize-numbytes); 00179 00180 numbytes= 0; 00181 jpeg_read_header(&dinfo, TRUE); 00182 if (dinfo.dc_huff_tbl_ptrs[0] == NULL){ 00183 std_huff_tables(&dinfo); 00184 } 00185 00186 jpeg_start_decompress(&dinfo); 00187 rowstride= dinfo.output_width*dinfo.output_components; 00188 for (y= 0; y<dinfo.output_height; y++){ 00189 jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1); 00190 outBuffer += rowstride; 00191 } 00192 jpeg_finish_decompress(&dinfo); 00193 jpeg_destroy_decompress(&dinfo); 00194 00195 return 1; 00196 } 00197 00198 static void Compress_JPEG(int quality, unsigned char *outbuffer, unsigned char *inBuffer, int width, int height, int bufsize) { 00199 int i, rowstride; 00200 unsigned int y; 00201 struct jpeg_compress_struct cinfo; 00202 struct jpeg_error_mgr jerr; 00203 unsigned char marker[60]; 00204 00205 cinfo.err = jpeg_std_error(&jerr); 00206 jpeg_create_compress(&cinfo); 00207 jpegmemdestmgr_build(&cinfo, outbuffer, bufsize); 00208 00209 cinfo.image_width = width; 00210 cinfo.image_height = height; 00211 cinfo.input_components = 3; 00212 cinfo.in_color_space = JCS_RGB; 00213 00214 jpeg_set_defaults(&cinfo); 00215 jpeg_set_colorspace (&cinfo, JCS_YCbCr); 00216 00217 jpeg_set_quality (&cinfo, quality, TRUE); 00218 00219 cinfo.dc_huff_tbl_ptrs[0]->sent_table = TRUE; 00220 cinfo.dc_huff_tbl_ptrs[1]->sent_table = TRUE; 00221 cinfo.ac_huff_tbl_ptrs[0]->sent_table = TRUE; 00222 cinfo.ac_huff_tbl_ptrs[1]->sent_table = TRUE; 00223 00224 cinfo.comp_info[0].component_id = 0; 00225 cinfo.comp_info[0].v_samp_factor = 1; 00226 cinfo.comp_info[1].component_id = 1; 00227 cinfo.comp_info[2].component_id = 2; 00228 00229 cinfo.write_JFIF_header = FALSE; 00230 00231 jpeg_start_compress(&cinfo, FALSE); 00232 00233 i=0; 00234 marker[i++] = 'A'; 00235 marker[i++] = 'V'; 00236 marker[i++] = 'I'; 00237 marker[i++] = '1'; 00238 marker[i++] = 0; 00239 while (i<60) 00240 marker[i++] = 32; 00241 00242 jpeg_write_marker (&cinfo, JPEG_APP0, marker, 60); 00243 00244 i=0; 00245 while (i<60) 00246 marker[i++] = 0; 00247 00248 jpeg_write_marker (&cinfo, JPEG_COM, marker, 60); 00249 00250 rowstride= cinfo.image_width*cinfo.input_components; 00251 for (y = 0; y < cinfo.image_height; y++){ 00252 jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &inBuffer, 1); 00253 inBuffer += rowstride; 00254 } 00255 jpeg_finish_compress(&cinfo); 00256 jpeg_destroy_compress(&cinfo); 00257 } 00258 00259 static void interlace(unsigned char *to, unsigned char *from, int width, int height) { 00260 int i, rowstride= width*3; 00261 00262 for (i=0; i<height; i++) { 00263 if (i&1) 00264 memcpy (&to[i*rowstride], &from[(i/2 + height/2)*rowstride], rowstride); 00265 else 00266 memcpy (&to[i*rowstride], &from[(i/2)*rowstride], rowstride); 00267 } 00268 } 00269 00270 static void deinterlace(int odd, unsigned char *to, unsigned char *from, int width, int height) { 00271 int i, rowstride= width*3; 00272 00273 for (i=0; i<height; i++) { 00274 if ((i&1)==odd) 00275 memcpy (&to[(i/2 + height/2)*rowstride], &from[i*rowstride], rowstride); 00276 else 00277 memcpy (&to[(i/2)*rowstride], &from[i*rowstride], rowstride); 00278 } 00279 } 00280 00281 static int check_and_decode_jpeg(unsigned char *inbuf, unsigned char *outbuf, int width, int height, int bufsize) { 00282 /* JPEG's are always multiples of 16, extra is cropped out AVI's */ 00283 if ((width&0xF) || (height&0xF)) { 00284 int i, rrowstride, jrowstride; 00285 int jwidth= PADUP(width, 16); 00286 int jheight= PADUP(height, 16); 00287 unsigned char *tmpbuf= MEM_mallocN(jwidth*jheight*3, "avi.check_and_decode_jpeg"); 00288 int ret= Decode_JPEG(inbuf, tmpbuf, jwidth, jheight, bufsize); 00289 00290 /* crop the tmpbuf into the real buffer */ 00291 rrowstride= width*3; 00292 jrowstride= jwidth*3; 00293 for (i=0; i<height; i++) 00294 memcpy(&outbuf[i*rrowstride], &tmpbuf[i*jrowstride], rrowstride); 00295 MEM_freeN(tmpbuf); 00296 00297 return ret; 00298 } else { 00299 return Decode_JPEG(inbuf, outbuf, width, height, bufsize); 00300 } 00301 } 00302 00303 static void check_and_compress_jpeg(int quality, unsigned char *outbuf, unsigned char *inbuf, int width, int height, int bufsize) { 00304 /* JPEG's are always multiples of 16, extra is ignored in AVI's */ 00305 if ((width&0xF) || (height&0xF)) { 00306 int i, rrowstride, jrowstride; 00307 int jwidth= PADUP(width, 16); 00308 int jheight= PADUP(height, 16); 00309 unsigned char *tmpbuf= MEM_mallocN(jwidth*jheight*3, "avi.check_and_compress_jpeg"); 00310 00311 /* resize the realbuf into the tmpbuf */ 00312 rrowstride= width*3; 00313 jrowstride= jwidth*3; 00314 for (i=0; i<jheight; i++) { 00315 if (i<height) 00316 memcpy(&tmpbuf[i*jrowstride], &inbuf[i*rrowstride], rrowstride); 00317 else 00318 memset(&tmpbuf[i*jrowstride], 0, rrowstride); 00319 memset(&tmpbuf[i*jrowstride+rrowstride], 0, jrowstride-rrowstride); 00320 } 00321 00322 Compress_JPEG(quality, outbuf, tmpbuf, jwidth, jheight, bufsize); 00323 00324 MEM_freeN(tmpbuf); 00325 } else { 00326 Compress_JPEG(quality, outbuf, inbuf, width, height, bufsize); 00327 } 00328 } 00329 00330 void *avi_converter_from_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size) { 00331 int deint; 00332 unsigned char *buf; 00333 00334 (void)stream; /* unused */ 00335 00336 buf= MEM_mallocN (movie->header->Height * movie->header->Width * 3, "avi.avi_converter_from_mjpeg 1"); 00337 00338 deint= check_and_decode_jpeg(buffer, buf, movie->header->Width, movie->header->Height, *size); 00339 00340 MEM_freeN(buffer); 00341 00342 if (deint) { 00343 buffer = MEM_mallocN (movie->header->Height * movie->header->Width * 3, "avi.avi_converter_from_mjpeg 2"); 00344 interlace (buffer, buf, movie->header->Width, movie->header->Height); 00345 MEM_freeN (buf); 00346 00347 buf= buffer; 00348 } 00349 00350 return buf; 00351 } 00352 00353 void *avi_converter_to_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size) { 00354 unsigned char *buf; 00355 int bufsize= *size; 00356 00357 numbytes = 0; 00358 *size= 0; 00359 00360 buf = MEM_mallocN (movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 1"); 00361 if (!movie->interlace) { 00362 check_and_compress_jpeg(movie->streams[stream].sh.Quality/100, buf, buffer, movie->header->Width, movie->header->Height, bufsize); 00363 } else { 00364 deinterlace (movie->odd_fields, buf, buffer, movie->header->Width, movie->header->Height); 00365 MEM_freeN (buffer); 00366 00367 buffer= buf; 00368 buf= MEM_mallocN (movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 2"); 00369 00370 check_and_compress_jpeg(movie->streams[stream].sh.Quality/100, buf, buffer, movie->header->Width, movie->header->Height/2, bufsize/2); 00371 *size+= numbytes; 00372 numbytes=0; 00373 check_and_compress_jpeg(movie->streams[stream].sh.Quality/100, buf+*size, buffer+(movie->header->Height/2)*movie->header->Width*3, movie->header->Width, movie->header->Height/2, bufsize/2); 00374 } 00375 *size += numbytes; 00376 00377 MEM_freeN (buffer); 00378 return buf; 00379 } 00380 00381 00382 /* Compression from memory */ 00383 00384 static void jpegmemdestmgr_init_destination(j_compress_ptr cinfo) { 00385 (void)cinfo; /* unused */ 00386 } 00387 00388 static boolean jpegmemdestmgr_empty_output_buffer(j_compress_ptr cinfo) { 00389 (void)cinfo; /* unused */ 00390 return TRUE; 00391 } 00392 00393 static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo) { 00394 numbytes-= cinfo->dest->free_in_buffer; 00395 00396 MEM_freeN(cinfo->dest); 00397 } 00398 00399 static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize) { 00400 cinfo->dest= MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build"); 00401 00402 cinfo->dest->init_destination= jpegmemdestmgr_init_destination; 00403 cinfo->dest->empty_output_buffer= jpegmemdestmgr_empty_output_buffer; 00404 cinfo->dest->term_destination= jpegmemdestmgr_term_destination; 00405 00406 cinfo->dest->next_output_byte= buffer; 00407 cinfo->dest->free_in_buffer= bufsize; 00408 00409 numbytes= bufsize; 00410 } 00411 00412 /* Decompression from memory */ 00413 00414 static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo) { 00415 (void)dinfo; 00416 } 00417 00418 static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo) { 00419 unsigned char *buf= (unsigned char*) dinfo->src->next_input_byte-2; 00420 00421 /* if we get called, must have run out of data */ 00422 WARNMS(dinfo, JWRN_JPEG_EOF); 00423 00424 buf[0]= (JOCTET) 0xFF; 00425 buf[1]= (JOCTET) JPEG_EOI; 00426 00427 dinfo->src->next_input_byte= buf; 00428 dinfo->src->bytes_in_buffer= 2; 00429 00430 return TRUE; 00431 } 00432 00433 static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skipcnt) { 00434 if (dinfo->src->bytes_in_buffer<skipcnt) 00435 skipcnt= dinfo->src->bytes_in_buffer; 00436 00437 dinfo->src->next_input_byte+= skipcnt; 00438 dinfo->src->bytes_in_buffer-= skipcnt; 00439 } 00440 00441 static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo) { 00442 numbytes-= dinfo->src->bytes_in_buffer; 00443 00444 MEM_freeN(dinfo->src); 00445 } 00446 00447 static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize) { 00448 dinfo->src= MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build"); 00449 00450 dinfo->src->init_source= jpegmemsrcmgr_init_source; 00451 dinfo->src->fill_input_buffer= jpegmemsrcmgr_fill_input_buffer; 00452 dinfo->src->skip_input_data= jpegmemsrcmgr_skip_input_data; 00453 dinfo->src->resync_to_restart= jpeg_resync_to_restart; 00454 dinfo->src->term_source= jpegmemsrcmgr_term_source; 00455 00456 dinfo->src->bytes_in_buffer= bufsize; 00457 dinfo->src->next_input_byte= buffer; 00458 00459 numbytes= bufsize; 00460 }