X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fjpeg2swf.c;h=a9a413caeabfbe774395289cdec6ed705f519785;hb=23c1c9363c730dfafc683bd00920a2c33cc07ee2;hp=cdcde70efab7db24fd57e9b8027db984aafca14d;hpb=fb8388aa3df14766cc0ab7a1c6274cfec774693d;p=swftools.git diff --git a/src/jpeg2swf.c b/src/jpeg2swf.c index cdcde70..a9a413c 100644 --- a/src/jpeg2swf.c +++ b/src/jpeg2swf.c @@ -1,441 +1,496 @@ -/* jpeg2swf.c - - JPEG to SWF converter tool - - Part of the swftools package. - - Copyright (c) 2001 Rainer Böhme - - This file is distributed under the GPL, see file COPYING for details - -*/ - -#include -#include -#include -#include -#include "../lib/rfxswf.h" -#include "../lib/args.h" // not really a header ;-) - -#define MAX_INPUT_FILES 1024 -#define VERBOSE(x) (global.verbose>=x) - -struct -{ int quality; - int framerate; - int max_image_width; - int max_image_height; - int force_width; - int force_height; - int nfiles; - int verbose; - char * files[MAX_INPUT_FILES]; - char * outfile; -} global; - -TAG * MovieStart(SWF * swf,int framerate,int dx,int dy) -{ TAG * t; - RGBA rgb; - - memset(swf,0x00,sizeof(SWF)); - - swf->FileVersion = 4; - swf->FrameRate = (25600/framerate); - swf->MovieSize.xmax = dx*20; - swf->MovieSize.ymax = dy*20; - - t = swf->FirstTag = InsertTag(NULL,ST_SETBACKGROUNDCOLOR); - - rgb.r = rgb.g = rgb.b = rgb.a = 0x00; - SetRGB(t,&rgb); - - return t; -} - -int MovieFinish(SWF * swf,TAG * t,char * sname) -{ int handle, so = fileno(stdout); - t = InsertTag(t,ST_END); - - if ((!isatty(so))&&(!sname)) handle = so; - else - { if (!sname) sname = "out.swf"; - handle = open(sname,O_RDWR|O_CREAT|O_TRUNC,0666); - } - if FAILED(WriteSWF(handle,swf)) if (VERBOSE(1)) fprintf(stderr,"Unable to write output file: %s\n",sname); - if (handle!=so) close(handle); - - FreeTags(swf); - return 0; -} - -TAG * MovieAddFrame(SWF * swf,TAG * t,char * sname,int quality,int id) -{ SHAPE * s; - SRECT r; - MATRIX m; - int fs; - - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - LPJPEGBITS out; - FILE * f; - U8 * scanline; - - if ((f=fopen(sname,"rb"))==NULL) - { if (VERBOSE(1)) fprintf(stderr,"Read access failed: %s\n",sname); - return t; - } - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,f); - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - t = InsertTag(t,ST_DEFINEBITSJPEG2); - - SetU16(t,id); // id - - out = SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality); - scanline = (U8*)malloc(4*cinfo.output_width); - - if (scanline) - { int y; - U8 * js = scanline; - for (y=0;yMovieSize.xmax-(int)cinfo.output_width*20)/2; - m.ty = (swf->MovieSize.ymax-(int)cinfo.output_height*20)/2; - ObjectPlace(t,id+1,1,&m,NULL,NULL); - - t = InsertTag(t,ST_SHOWFRAME); - - jpeg_finish_decompress(&cinfo); - fclose(f); - - return t; -} - -int CheckInputFile(char * fname,char ** realname) -{ struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - FILE * f; - char * s = malloc(strlen(fname)+5); - - if (!s) exit(2); - (*realname) = s; - strcpy(s,fname); - - // Check whether file exists (with typical extensions) - - if ((f=fopen(s,"rb"))==NULL) - { sprintf(s,"%s.jpg",fname); - if ((f=fopen(s,"rb"))==NULL) - { sprintf(s,"%s.jpeg",fname); - if ((f=fopen(s,"rb"))==NULL) - { sprintf(s,"%s.JPG",fname); - if ((f=fopen(s,"rb"))==NULL) - { sprintf(s,"%s.JPEG",fname); - if ((f=fopen(s,"rb"))==NULL) - return 0; - } - } - } - } - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,f); - jpeg_read_header(&cinfo, TRUE); - - // Get image dimensions - - if (global.max_image_width100)) - { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid quality between 1 and 100.\n"); - exit(1); - } - res = 1; - break; - - case 'r': - if (val) global.framerate = atoi(val); - if ((global.framerate<1)||(global.framerate>5000)) - { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid framerate between 1 and 10000.\n"); - exit(1); - } - res = 1; - break; - - case 'o': - if (val) global.outfile = val; res = 1; break; - - case 'v': - if (val) global.verbose = atoi(val); res = 1; break; - - case 'X': - if (val) global.force_width = atoi(val); res = 1; break; - - case 'Y': - if (val) global.force_height = atoi(val); res = 1; break; - - case 'V': - printf("jpeg2swf - part of %s %s\n", PACKAGE, VERSION);exit(0); - - default: - res = -1; - break; - } - - if (res<0) - { if (VERBOSE(1)) fprintf(stderr,"Unknown option: -v%s\n",arg); - return 0; - } - return res; -} - -struct options_t -{ char*shortoption; - char*longoption; -} options[] = -{{"q","quality"}, - {"o","output"}, - {"r","rate"}, - {"v","verbose"}, - {"X","width"}, - {"Y","height"}, - {"v","verbose"}, - {"V","version"} -}; - -int args_callback_longoption(char*name,char*val) { - int t; - for(t=0;t=MAX_INPUT_FILES) - { if (VERBOSE(1)) fprintf(stderr, "Error: Too many input files.\n"); - exit(1); - } - } - return 0; -} - -void args_callback_usage(char*name) -{ fprintf(stderr,"Usage: %s imagefiles[.jpg]|[.jpeg] [...] [-options [value]]\n",name); - fprintf(stderr,"-q quality (quality) Set JPEG compression quality (1-100)\n"); - fprintf(stderr,"-r framerate (rate) Set movie framerate (100/sec)\n"); - fprintf(stderr,"-o outputfile (output) Set name for SWF output file\n"); - fprintf(stderr,"-v level (verbose) Set verbose level (0=quiet, 1=default, 2=debug)\n"); - fprintf(stderr,"-X pixel (width) Force movie width to scale (default: autodetect)\n"); - fprintf(stderr,"-Y pixel (height) Force movie height to scale (default: autodetect)\n"); - fprintf(stderr,"-V (version) Print version information and exit\n"); -} - - -int main(int argc, char ** argv) -{ SWF swf; - TAG * t; - - memset(&global,0x00,sizeof(global)); - - global.quality = 60; - global.framerate = 100; - global.verbose = 1; - - processargs(argc, argv); - - if (VERBOSE(2)) fprintf(stderr,"Processing %i file(s)...\n",global.nfiles); - - t = MovieStart(&swf,global.framerate, - global.force_width?global.force_width:global.max_image_width, - global.force_height?global.force_height:global.max_image_height); - - { int i; - for (i=0;i + + This file is distributed under the GPL, see file COPYING for details + +*/ + +#include +#include +#include +#include +#include "../lib/rfxswf.h" +#include "../lib/args.h" // not really a header ;-) + +#define MAX_INPUT_FILES 1024 +#define VERBOSE(x) (global.verbose>=x) + +struct +{ int quality; + int framerate; + int max_image_width; + int max_image_height; + int force_width; + int force_height; + int prescale; + int nfiles; + int verbose; + char * outfile; +} global; + +struct +{ char * filename; + int scale; + int quality; +} image[MAX_INPUT_FILES]; + +TAG * MovieStart(SWF * swf,int framerate,int dx,int dy) +{ TAG * t; + RGBA rgb; + + memset(swf,0x00,sizeof(SWF)); + + swf->fileVersion = 4; + swf->frameRate = (25600/framerate); + swf->movieSize.xmax = dx*20; + swf->movieSize.ymax = dy*20; + + t = swf->firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR); + + rgb.r = rgb.g = rgb.b = rgb.a = 0x00; + swf_SetRGB(t,&rgb); + + return t; +} + +int MovieFinish(SWF * swf,TAG * t,char * sname) +{ int handle, so = fileno(stdout); + t = swf_InsertTag(t,ST_END); + + if ((!isatty(so))&&(!sname)) handle = so; + else + { if (!sname) sname = "output.swf"; + handle = open(sname,O_RDWR|O_CREAT|O_TRUNC,0666); + } + if FAILED(swf_WriteSWF(handle,swf)) if (VERBOSE(1)) fprintf(stderr,"Unable to write output file: %s\n",sname); + if (handle!=so) close(handle); + + swf_FreeTags(swf); + return 0; +} + +TAG * MovieAddFrame(SWF * swf,TAG * t,char * sname,int quality,int scale,int id) +{ SHAPE * s; + SRECT r; + MATRIX m; + int fs; + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + LPJPEGBITS out; + FILE * f; + U8 * scanline; + + if ((f=fopen(sname,"rb"))==NULL) + { if (VERBOSE(1)) fprintf(stderr,"Read access failed: %s\n",sname); + return t; + } + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo,f); + jpeg_read_header(&cinfo, TRUE); + + if (scale>1) + { cinfo.scale_num = 1; + cinfo.scale_denom = scale; + } + + jpeg_start_decompress(&cinfo); + + t = swf_InsertTag(t,ST_DEFINEBITSJPEG2); + + swf_SetU16(t,id); // id + + out = swf_SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality); + scanline = (U8*)malloc(4*cinfo.output_width); + + // the following code is a duplication of swf_SetJPEGBits in ../lib/modules/swfbits.c + if (scanline) + { int y; + U8 * js = scanline; + + if(cinfo.out_color_space == JCS_GRAYSCALE) + { + for (y=0;y=0;x--) { + js[x*3] = js[x*3+1] = js[x*3+2] = js[x]; + } + swf_SetJPEGBitsLines(out,(U8**)&js,1); + } + } + else if(cinfo.out_color_space == JCS_RGB) + { + for (y=0;ymovieSize.xmax-(int)cinfo.output_width*20)/2; + m.ty = (swf->movieSize.ymax-(int)cinfo.output_height*20)/2; + swf_ObjectPlace(t,id+1,1,&m,NULL,NULL); + + t = swf_InsertTag(t,ST_SHOWFRAME); + + jpeg_finish_decompress(&cinfo); + fclose(f); + + return t; +} + +int CheckInputFile(char * fname,char ** realname) +{ struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE * f; + char * s = malloc(strlen(fname)+5); + int width, height; + + if (!s) exit(2); + (*realname) = s; + strcpy(s,fname); + + // Check whether file exists (with typical extensions) + + if ((f=fopen(s,"rb"))==NULL) + { sprintf(s,"%s.jpg",fname); + if ((f=fopen(s,"rb"))==NULL) + { sprintf(s,"%s.jpeg",fname); + if ((f=fopen(s,"rb"))==NULL) + { sprintf(s,"%s.JPG",fname); + if ((f=fopen(s,"rb"))==NULL) + { sprintf(s,"%s.JPEG",fname); + if ((f=fopen(s,"rb"))==NULL) + return -1; + } + } + } + } + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo,f); + jpeg_read_header(&cinfo, TRUE); + + // Apply scaling (scale option can be used several times to set different scales) + + if (global.prescale>1) + { cinfo.scale_num = 1; + cinfo.scale_denom = global.prescale; + + jpeg_calc_output_dimensions(&cinfo); + + width = cinfo.output_width; + height = cinfo.output_height; + } + else + { width = cinfo.image_width; + height = cinfo.image_height; + } + + // Get image dimensions + + if (global.max_image_width100)) + { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid quality between 1 and 100.\n"); + exit(1); + } + res = 1; + break; + + case 'r': + if (val) global.framerate = atoi(val); + if ((global.framerate<1)||(global.framerate>5000)) + { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid framerate between 1 and 10000.\n"); + exit(1); + } + res = 1; + break; + + case 's': + if (val) global.prescale = atoi(val); + if (!((global.prescale==1)||(global.prescale==2)||(global.prescale==4)||(global.prescale==8))) + { if (VERBOSE(1)) fprintf(stderr,"Error: Prescale denominator is limited to 2, 4 or 8\n"); + exit(1); + } + res = 1; + break; + + case 'o': + if (val) global.outfile = val; res = 1; break; + + case 'v': + if (val) global.verbose = atoi(val); res = 1; break; + + case 'X': + if (val) global.force_width = atoi(val); res = 1; break; + + case 'Y': + if (val) global.force_height = atoi(val); res = 1; break; + + case 'V': + printf("jpeg2swf - part of %s %s\n", PACKAGE, VERSION);exit(0); + + default: + res = -1; + break; + } + + if (res<0) + { if (VERBOSE(1)) fprintf(stderr,"Unknown option: -%s\n",arg); + exit(1); + return 0; + } + return res; +} + +struct options_t options[] = +{{"q","quality"}, + {"o","output"}, + {"r","rate"}, + {"v","verbose"}, + {"X","width"}, + {"Y","height"}, + {"V","version"}, + {"s","scale"} + }; + +int args_callback_longoption(char*name,char*val) { + return args_long2shortoption(options, name, val); +} + +int args_callback_command(char*arg,char*next) // actually used as filename +{ char * s; + int scale; + if (CheckInputFile(arg,&s)<0) + { if (VERBOSE(1)) fprintf(stderr, "Unable to open input file: %s\n",arg); + free(s); + } + else + { image[global.nfiles].filename = s; + image[global.nfiles].scale = global.prescale; + image[global.nfiles].quality = global.quality; + global.nfiles++; + if (global.nfiles>=MAX_INPUT_FILES) + { if (VERBOSE(1)) fprintf(stderr, "Error: Too many input files.\n"); + exit(1); + } + } + return 0; +} + +void args_callback_usage(char*name) +{ fprintf(stderr,"Usage: %s [-options [value]] imagefiles[.jpg]|[.jpeg] [...]\n",name); + fprintf(stderr,"-q quality (quality) Set JPEG compression quality (1-100)\n"); + fprintf(stderr,"-s denominator (scale) 2, 4 or 8: Reduce image size to 1/2, 1/4, 1/8\n"); + fprintf(stderr,"-r framerate (rate) Set movie framerate (100/sec)\n"); + fprintf(stderr,"-o outputfile (output) Set name for SWF output file\n"); + fprintf(stderr,"-X pixel (width) Force movie width to scale (default: autodetect)\n"); + fprintf(stderr,"-Y pixel (height) Force movie height to scale (default: autodetect)\n"); + fprintf(stderr,"-v level (verbose) Set verbose level (0=quiet, 1=default, 2=debug)\n"); + fprintf(stderr,"-V (version) Print version information and exit\n"); + fprintf(stderr,"The following options can be set independently for each image: -q -s\n"); +} + + +int main(int argc, char ** argv) +{ SWF swf; + TAG * t; + + memset(&global,0x00,sizeof(global)); + + global.quality = 60; + global.framerate = 100; + global.verbose = 1; + global.prescale = 1; + + processargs(argc, argv); + + if (VERBOSE(2)) fprintf(stderr,"Processing %i file(s)...\n",global.nfiles); + + t = MovieStart(&swf,global.framerate, + global.force_width?global.force_width:global.max_image_width, + global.force_height?global.force_height:global.max_image_height); + + { int i; + for (i=0;i