diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/export/export_jpg.c')
-rw-r--r-- | debian/transcode/transcode-1.1.7/export/export_jpg.c | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/export/export_jpg.c b/debian/transcode/transcode-1.1.7/export/export_jpg.c new file mode 100644 index 00000000..31975393 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/export/export_jpg.c @@ -0,0 +1,349 @@ +/* + * export_jpg.c + * + * Copyright (C) Tilmann Bitterberg - September 2002 + * + * This file is part of transcode, a video stream processing tool + * + * transcode is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define MOD_NAME "export_jpg.so" +#define MOD_VERSION "v0.2.1 (2003-08-06)" +#define MOD_CODEC "(video) *" + +#include "transcode.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "jpeglib.h" + +static int verbose_flag=TC_QUIET; +static int capability_flag=TC_CAP_YUV|TC_CAP_RGB|TC_CAP_PCM|TC_CAP_AUD; + +#define MOD_PRE jpg +#include "export_def.h" + +static char buf2[PATH_MAX]; + +static int codec, width, height; + +static int counter=0; +static const char *prefix="frame."; +static int jpeg_quality =0; +#define JPEG_DEFAULT_QUALITY 85 + +static int interval=1; +static unsigned int int_counter=0; + +JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */ +static unsigned char **line[3]; + +/* ------------------------------------------------------------ + * + * init codec + * + * ------------------------------------------------------------*/ + +// native YUV jpeg encoder code based on encode_JPEG of the quicktime4linux lib +// +static void write_yuv_JPEG_file(char *filename, int quality, + unsigned char **input, + int _width, int _height) +{ + int i, j, k; + int width = _width; + int height = _height; + unsigned char *base[3]; + struct jpeg_compress_struct encinfo; + struct jpeg_error_mgr jerr; + FILE * outfile; /* target file */ + + jpeg_create_compress(&encinfo); + + encinfo.err = jpeg_std_error(&jerr); + + if ((outfile = fopen(filename, "wb")) == NULL) { + tc_log_error(MOD_NAME, "can't open %s", filename); + } + jpeg_stdio_dest(&encinfo, outfile); + + encinfo.image_width = width; + encinfo.image_height = height; + encinfo.input_components = 3; + + jpeg_set_defaults(&encinfo); + encinfo.dct_method = JDCT_FASTEST; + + jpeg_set_quality(&encinfo, quality, TRUE); + encinfo.raw_data_in = TRUE; +#if JPEG_LIB_VERSION >= 70 + encinfo.do_fancy_downsampling = FALSE; +#endif + encinfo.in_color_space = JCS_YCbCr; + + encinfo.comp_info[0].h_samp_factor = 2; + encinfo.comp_info[0].v_samp_factor = 2; + encinfo.comp_info[1].h_samp_factor = 1; + encinfo.comp_info[1].v_samp_factor = 1; + encinfo.comp_info[2].h_samp_factor = 1; + encinfo.comp_info[2].v_samp_factor = 1; + + jpeg_start_compress(&encinfo, TRUE); + + base[0] = input[0]; + base[1] = input[1]; + base[2] = input[2]; + + for (i = 0; i < height; i += 2*DCTSIZE) { + for (j=0, k=0; j<2*DCTSIZE;j+=2, k++) { + + line[0][j] = base[0]; base[0] += width; + line[0][j+1] = base[0]; base[0] += width; + line[1][k] = base[1]; base[1] += width/2; + line[2][k] = base[2]; base[2] += width/2; + } + jpeg_write_raw_data(&encinfo, line, 2*DCTSIZE); + } + jpeg_finish_compress(&encinfo); + + fclose(outfile); + + jpeg_destroy_compress(&encinfo); + +} + +static void write_rgb_JPEG_file (char * filename, int quality, int width, int height) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + /* More stuff */ + FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + /* Step 1: allocate and initialize JPEG compression object */ + + cinfo.err = jpeg_std_error(&jerr); + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + if ((outfile = fopen(filename, "wb")) == NULL) { + tc_log_error(MOD_NAME, "can't open %s", filename); + } + jpeg_stdio_dest(&cinfo, outfile); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = width; /* image width and height, in pixels */ + cinfo.image_height = height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, quality, TRUE); /* limit to baseline-JPEG values */ + + /* Step 4: Start compressor */ + + /* TRUE ensures that we will write a complete interchange-JPEG file. + * Pass TRUE unless you are very sure of what you're doing. + */ + jpeg_start_compress(&cinfo, TRUE); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + row_stride = cinfo.image_width * 3; /* JSAMPLEs per row in image_buffer */ + + while (cinfo.next_scanline < cinfo.image_height) { + row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + /* After finish_compress, we can close the output file. */ + fclose(outfile); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + +} + +MOD_init +{ + + /* set the 'spit-out-frame' interval */ + interval = vob->frame_interval; + + if(param->flag == TC_VIDEO) { + + width = vob->ex_v_width; + height = vob->ex_v_height; + + codec = (vob->im_v_codec == CODEC_YUV) ? CODEC_YUV : CODEC_RGB; + + if(vob->im_v_codec == CODEC_YUV) { + line[0] = malloc(height*sizeof(char*)); + line[1] = malloc(height*sizeof(char*)/2); + line[2] = malloc(height*sizeof(char*)/2); + } + + return(0); + } + + if(param->flag == TC_AUDIO) return(0); + + // invalid flag + return(TC_EXPORT_ERROR); +} + +/* ------------------------------------------------------------ + * + * open outputfile + * + * ------------------------------------------------------------*/ + +MOD_open +{ + + if(param->flag == TC_VIDEO) { + + // video + + switch(vob->im_v_codec) { + + case CODEC_YUV: + case CODEC_RGB: + + if(vob->video_out_file!=NULL && strcmp(vob->video_out_file,"/dev/null")!=0) prefix=vob->video_out_file; + + break; + + default: + + tc_log_warn(MOD_NAME, "codec not supported (0x%x)", vob->im_v_codec); + return(TC_EXPORT_ERROR); + + break; + } + + if(vob->ex_v_fcc != NULL && strlen(vob->ex_v_fcc) != 0) { + jpeg_quality=atoi(vob->ex_v_fcc); + if (jpeg_quality<=0) jpeg_quality = JPEG_DEFAULT_QUALITY; + if (jpeg_quality>100) jpeg_quality = 100; + } else { + jpeg_quality=75; + } + + return(0); + } + + + if(param->flag == TC_AUDIO) return(0); + + // invalid flag + return(TC_EXPORT_ERROR); +} + +/* ------------------------------------------------------------ + * + * encode and export + * + * ------------------------------------------------------------*/ + +MOD_encode +{ + + char *out_buffer = param->buffer; + + if ((++int_counter-1) % interval != 0) + return (0); + + if(param->flag == TC_VIDEO) { + + + if(tc_snprintf(buf2, PATH_MAX, "%s%06d.%s", prefix, counter++, "jpg") < 0) { + tc_log_perror(MOD_NAME, "cmd buffer overflow"); + return(TC_EXPORT_ERROR); + } + + if(codec==CODEC_YUV) { + unsigned char *base[3]; + YUV_INIT_PLANES(base, param->buffer, IMG_YUV420P, width, height); + write_yuv_JPEG_file(buf2, jpeg_quality, base, width, height); + + //out_buffer = tmp_buffer; + } else { + image_buffer = out_buffer; + write_rgb_JPEG_file(buf2, jpeg_quality, width, height); + } + + return(0); + } + + if(param->flag == TC_AUDIO) return(0); + + // invalid flag + return(TC_EXPORT_ERROR); +} + +/* ------------------------------------------------------------ + * + * stop encoder + * + * ------------------------------------------------------------*/ + +MOD_stop +{ + + if(param->flag == TC_VIDEO) { + return(0); + } + + if(param->flag == TC_AUDIO) return(0); + + return(TC_EXPORT_ERROR); +} + +/* ------------------------------------------------------------ + * + * close outputfiles + * + * ------------------------------------------------------------*/ + +MOD_close +{ + + if(param->flag == TC_AUDIO) return(0); + if(param->flag == TC_VIDEO) return(0); + + return(TC_EXPORT_ERROR); + +} |