Blender V2.61 - r43446

mjpeg.c

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