-/* jpeg2swf.c\r
-\r
- JPEG to SWF converter tool\r
-\r
- Part of the swftools package.\r
-\r
- Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
- \r
- This file is distributed under the GPL, see file COPYING for details \r
-\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <math.h>\r
-#include <fcntl.h>\r
-#include <jpeglib.h>\r
-#include "../lib/rfxswf.h"\r
-\r
-#include "args.h" // not really a header ;-)\r
-\r
-#define MAX_INPUT_FILES 1024\r
-#define VERBOSE(x) (global.verbose>=x)\r
-\r
-struct\r
-{ int quality;\r
- int framerate;\r
- int max_image_width;\r
- int max_image_height;\r
- int force_width;\r
- int force_height;\r
- int nfiles;\r
- int verbose;\r
- char * files[MAX_INPUT_FILES];\r
- char * outfile;\r
-} global;\r
-\r
-TAG * MovieStart(SWF * swf,int framerate,int dx,int dy)\r
-{ TAG * t;\r
- RGBA rgb;\r
-\r
- memset(swf,0x00,sizeof(SWF));\r
-\r
- swf->FileVersion = 4;\r
- swf->FrameRate = (25600/framerate);\r
- swf->MovieSize.xmax = dx*20;\r
- swf->MovieSize.ymax = dy*20;\r
-\r
- t = swf->FirstTag = InsertTag(NULL,ST_SETBACKGROUNDCOLOR);\r
-\r
- rgb.r = rgb.g = rgb.b = rgb.a = 0x00;\r
- SetRGB(t,&rgb);\r
-\r
- return t;\r
-}\r
-\r
-int MovieFinish(SWF * swf,TAG * t,char * sname)\r
-{ int handle, so = fileno(stdout);\r
- t = InsertTag(t,ST_END);\r
-\r
- if ((!isatty(so))&&(!sname)) handle = so;\r
- else\r
- { if (!sname) sname = "out.swf";\r
- handle = open(sname,O_RDWR|O_CREAT|O_TRUNC,0666);\r
- }\r
- if FAILED(WriteSWF(handle,swf)) if (VERBOSE(1)) fprintf(stderr,"Unable to write output file: %s\n",sname);\r
- if (handle!=so) close(handle);\r
- \r
- FreeTags(swf);\r
- return 0;\r
-}\r
-\r
-TAG * MovieAddFrame(SWF * swf,TAG * t,char * sname,int quality,int id)\r
-{ SHAPE * s;\r
- SRECT r;\r
- MATRIX m;\r
- int fs;\r
- \r
- struct jpeg_decompress_struct cinfo;\r
- struct jpeg_error_mgr jerr;\r
- LPJPEGBITS out;\r
- FILE * f;\r
- U8 * scanline;\r
-\r
- if ((f=fopen(sname,"rb"))==NULL)\r
- { if (VERBOSE(1)) fprintf(stderr,"Read access failed: %s\n",sname);\r
- return t;\r
- }\r
- \r
- cinfo.err = jpeg_std_error(&jerr);\r
- jpeg_create_decompress(&cinfo); \r
- jpeg_stdio_src(&cinfo,f);\r
- jpeg_read_header(&cinfo, TRUE);\r
- jpeg_start_decompress(&cinfo);\r
-\r
- t = InsertTag(t,ST_DEFINEBITSJPEG2);\r
-\r
- SetU16(t,id); // id\r
- \r
- out = SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality);\r
- scanline = (U8*)malloc(4*cinfo.output_width);\r
- \r
- if (scanline)\r
- { int y;\r
- U8 * js = scanline;\r
- for (y=0;y<cinfo.output_height;y++)\r
- { jpeg_read_scanlines(&cinfo,&js,1);\r
- SetJPEGBitsLines(out,(U8**)&js,1);\r
- }\r
- free(scanline);\r
- }\r
- \r
- SetJPEGBitsFinish(out);\r
- \r
- t = InsertTag(t,ST_DEFINESHAPE);\r
-\r
- NewShape(&s);\r
- GetMatrix(NULL,&m);\r
- m.sx = 20*0x10000;\r
- m.sy = 20*0x10000;\r
- fs = ShapeAddBitmapFillStyle(s,&m,id,0);\r
- \r
- SetU16(t,id+1); // id\r
-\r
-\r
- r.xmin = r.ymin = 0;\r
- r.xmax = cinfo.output_width*20;\r
- r.ymax = cinfo.output_height*20;\r
- SetRect(t,&r);\r
- \r
- SetShapeHeader(t,s);\r
-\r
- ShapeSetAll(t,s,0,0,0,fs,0);\r
- ShapeSetLine(t,s,r.xmax,0);\r
- ShapeSetLine(t,s,0,r.ymax);\r
- ShapeSetLine(t,s,-r.xmax,0);\r
- ShapeSetLine(t,s,0,-r.ymax);\r
- \r
- ShapeSetEnd(t);\r
- \r
- t = InsertTag(t,ST_REMOVEOBJECT2);\r
- SetU16(t,1); // depth\r
-\r
- t = InsertTag(t,ST_PLACEOBJECT2);\r
-\r
- GetMatrix(NULL,&m);\r
- m.tx = (swf->MovieSize.xmax-(int)cinfo.output_width*20)/2;\r
- m.ty = (swf->MovieSize.ymax-(int)cinfo.output_height*20)/2;\r
- ObjectPlace(t,id+1,1,&m,NULL,NULL);\r
-\r
- t = InsertTag(t,ST_SHOWFRAME);\r
-\r
- jpeg_finish_decompress(&cinfo);\r
- fclose(f);\r
-\r
- return t;\r
-}\r
-\r
-int CheckInputFile(char * fname,char ** realname)\r
-{ struct jpeg_decompress_struct cinfo;\r
- struct jpeg_error_mgr jerr;\r
- FILE * f;\r
- char * s = malloc(strlen(fname)+5);\r
- \r
- if (!s) exit(2);\r
- (*realname) = s;\r
- strcpy(s,fname);\r
-\r
- // Check whether file exists (with typical extensions)\r
-\r
- if ((f=fopen(s,"rb"))==NULL)\r
- { sprintf(s,"%s.jpg",fname);\r
- if ((f=fopen(s,"rb"))==NULL)\r
- { sprintf(s,"%s.jpeg",fname);\r
- if ((f=fopen(s,"rb"))==NULL)\r
- { sprintf(s,"%s.JPG",fname);\r
- if ((f=fopen(s,"rb"))==NULL)\r
- { sprintf(s,"%s.JPEG",fname);\r
- if ((f=fopen(s,"rb"))==NULL)\r
- return 0;\r
- }\r
- }\r
- }\r
- }\r
- \r
- cinfo.err = jpeg_std_error(&jerr);\r
- jpeg_create_decompress(&cinfo); \r
- jpeg_stdio_src(&cinfo,f);\r
- jpeg_read_header(&cinfo, TRUE);\r
-\r
- // Get image dimensions\r
-\r
- if (global.max_image_width<cinfo.image_width) global.max_image_width = cinfo.image_width;\r
- if (global.max_image_height<cinfo.image_height) global.max_image_height = cinfo.image_height;\r
- \r
- jpeg_destroy_decompress(&cinfo);\r
- fclose(f);\r
-\r
- return 0;\r
-}\r
-\r
-int args_callback_option(char*arg,char*val)\r
-{ int res = 0;\r
- if (arg[1]) res = -1;\r
- else switch (arg[0])\r
- { case 'q':\r
- if (val) global.quality = atoi(val);\r
- if ((global.quality<1)||(global.quality>100))\r
- { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid quality between 1 and 100.\n");\r
- exit(1);\r
- }\r
- res = 1;\r
- break;\r
-\r
- case 'r':\r
- if (val) global.framerate = atoi(val);\r
- if ((global.framerate<1)||(global.framerate>5000))\r
- { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid framerate between 1 and 10000.\n");\r
- exit(1);\r
- }\r
- res = 1;\r
- break;\r
-\r
- case 'o':\r
- if (val) global.outfile = val; res = 1; break;\r
-\r
- case 'v':\r
- if (val) global.verbose = atoi(val); res = 1; break;\r
-\r
- case 'X':\r
- if (val) global.force_width = atoi(val); res = 1; break;\r
-\r
- case 'Y':\r
- if (val) global.force_height = atoi(val); res = 1; break;\r
-\r
- case 'V':\r
- printf("jpeg2swf - part of swftools 0.0.1\n");exit(0);\r
- \r
- default:\r
- res = -1;\r
- break;\r
- }\r
- \r
- if (res<0)\r
- { if (VERBOSE(1)) fprintf(stderr,"Unknown option: -v%s\n",arg);\r
- return 0;\r
- }\r
- return res;\r
-}\r
-\r
-struct options_t\r
-{ char*shortoption;\r
- char*longoption;\r
-} options[] =\r
-{{"q","quality"},\r
- {"o","output"},\r
- {"r","rate"},\r
- {"v","verbose"},\r
- {"X","width"},\r
- {"Y","height"},\r
- {"v","verbose"},\r
- {"V","version"}\r
-};\r
-\r
-int args_callback_longoption(char*name,char*val) {\r
- int t;\r
- for(t=0;t<sizeof(options)/sizeof(struct options_t);t++)\r
- if(!strcmp(options[t].longoption, name))\r
- return args_callback_option(options[t].shortoption,val);\r
- if (VERBOSE(1)) fprintf(stderr, "Unknown option: --%s\n", name);\r
- exit(1);\r
-}\r
-\r
-int args_callback_command(char*arg,char*next) // actually used as filename\r
-{ char * s;\r
- if (CheckInputFile(arg,&s)<0)\r
- { if (VERBOSE(1)) fprintf(stderr, "Unable to open input file: %s\n",arg);\r
- free(s);\r
- }\r
- else\r
- { global.files[global.nfiles] = s;\r
- global.nfiles++;\r
- if (global.nfiles>=MAX_INPUT_FILES)\r
- { if (VERBOSE(1)) fprintf(stderr, "Error: Too many input files.\n");\r
- exit(1);\r
- }\r
- }\r
- return 0;\r
-}\r
-\r
-void args_callback_usage(char*name)\r
-{ fprintf(stderr,"Usage: %s imagefiles[.jpg]|[.jpeg] [...] [-options [value]]\n",name);\r
- fprintf(stderr,"-q quality (quality) Set JPEG compression quality (1-100)\n");\r
- fprintf(stderr,"-r framerate (rate) Set movie framerate (100/sec)\n");\r
- fprintf(stderr,"-o outputfile (output) Set name for SWF output file\n");\r
- fprintf(stderr,"-v level (verbose) Set verbose level (0=quiet, 1=default, 2=debug)\n");\r
- fprintf(stderr,"-X pixel (width) Force movie width to scale (default: autodetect)\n");\r
- fprintf(stderr,"-Y pixel (height) Force movie height to scale (default: autodetect)\n");\r
- fprintf(stderr,"-V (version) Print version information and exit\n");\r
-}\r
-\r
-\r
-int main(int argc, char ** argv)\r
-{ SWF swf;\r
- TAG * t;\r
-\r
- memset(&global,0x00,sizeof(global));\r
- \r
- global.quality = 60;\r
- global.framerate = 100;\r
- global.verbose = 1;\r
- \r
- processargs(argc, argv);\r
-\r
- if (VERBOSE(2)) fprintf(stderr,"Processing %i file(s)...\n",global.nfiles);\r
-\r
- t = MovieStart(&swf,global.framerate,\r
- global.force_width?global.force_width:global.max_image_width,\r
- global.force_height?global.force_height:global.max_image_height);\r
-\r
- { int i;\r
- for (i=0;i<global.nfiles;i++)\r
- { if (VERBOSE(3)) fprintf(stderr,"[%03i] %s\n",i,global.files[i]);\r
- t = MovieAddFrame(&swf,t,global.files[i],global.quality,(i*2)+1);\r
- free(global.files[i]);\r
- }\r
- }\r
-\r
- MovieFinish(&swf,t,global.outfile);\r
-\r
- return 0;\r
-}\r
-\r
-\r
-// Old main routine\r
-\r
-/*\r
-int ConvertJPEG2SWF(char * sname,char * dname,int quality)\r
-{ RGBA rgb;\r
- SWF swf;\r
- TAG * t;\r
- \r
- SHAPE * s;\r
- SRECT r;\r
- MATRIX m;\r
- int fs;\r
- \r
- struct jpeg_decompress_struct cinfo;\r
- struct jpeg_error_mgr jerr;\r
- LPJPEGBITS out;\r
- FILE * f;\r
- U8 * scanline;\r
-\r
- int handle;\r
-\r
- cinfo.err = jpeg_std_error(&jerr);\r
- jpeg_create_decompress(&cinfo); \r
-\r
- if ((f=fopen(sname,"rb"))==NULL)\r
- { fprintf(stderr,"Read access failed: %s\n",sname);\r
- return -1;\r
- }\r
- \r
- jpeg_stdio_src(&cinfo,f);\r
- jpeg_read_header(&cinfo, TRUE);\r
- jpeg_start_decompress(&cinfo);\r
- \r
- memset(&swf,0x00,sizeof(SWF));\r
-\r
- swf.FileVersion = 4;\r
- swf.FrameRate = 0x1000;\r
- swf.MovieSize.xmax = cinfo.output_width*20;\r
- swf.MovieSize.ymax = cinfo.output_height*20;\r
-\r
- printf("dx = %i, dy = %i\n",cinfo.output_width,cinfo.output_height);\r
-\r
- t = swf.FirstTag = InsertTag(NULL,ST_SETBACKGROUNDCOLOR);\r
-\r
- rgb.r = rgb.g = rgb.b = rgb.a = 0x00;\r
- SetRGB(t,&rgb);\r
-\r
- t = InsertTag(t,ST_DEFINEBITSJPEG2);\r
-\r
- SetU16(t,1); // id\r
- \r
- out = SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality);\r
- scanline = (U8*)malloc(4*cinfo.output_width);\r
- \r
- if (scanline)\r
- { int y;\r
- U8 * js = scanline;\r
- for (y=0;y<cinfo.output_height;y++)\r
- { jpeg_read_scanlines(&cinfo,&js,1);\r
- SetJPEGBitsLines(out,(U8**)&js,1);\r
- }\r
- free(scanline);\r
- }\r
- \r
- SetJPEGBitsFinish(out);\r
-\r
- printf("JPEG Tag-Length: %06x\n",GetDataSize(t));\r
-\r
- t = InsertTag(t,ST_DEFINESHAPE);\r
-\r
- NewShape(&s);\r
- GetMatrix(NULL,&m);\r
- m.sx = 20*0x10000;\r
- m.sy = 20*0x10000;\r
- rgb.r = 0xff;\r
- fs = ShapeAddBitmapFillStyle(s,&m,1,0);\r
-// fs = ShapeAddSolidFillStyle(s,&rgb);\r
- \r
- SetU16(t,2); // id\r
- SetRect(t,&swf.MovieSize);\r
- SetShapeHeader(t,s);\r
-\r
- ShapeSetAll(t,s,0,0,0,fs,0);\r
- ShapeSetLine(t,s,swf.MovieSize.xmax,0);\r
- ShapeSetLine(t,s,0,swf.MovieSize.ymax);\r
- ShapeSetLine(t,s,-swf.MovieSize.xmax,0);\r
- ShapeSetLine(t,s,0,-swf.MovieSize.ymax);\r
- \r
- ShapeSetEnd(t);\r
-\r
- t = InsertTag(t,ST_PLACEOBJECT2);\r
-\r
- ObjectPlace(t,2,1,NULL,NULL,NULL);\r
-\r
- t = InsertTag(t,ST_SHOWFRAME);\r
- \r
- t = InsertTag(t,ST_END);\r
-\r
- jpeg_finish_decompress(&cinfo);\r
- fclose(f);\r
- \r
- handle = open(dname,O_RDWR|O_CREAT|O_TRUNC,0666);\r
- if FAILED(WriteSWF(handle,&swf)) fprintf(stderr,"WriteSWF() failed.\n");\r
- close(handle);\r
-\r
- return 0;\r
-}\r
-*/\r
-\r
+/* jpeg2swf.c
+
+ JPEG to SWF converter tool
+
+ Part of the swftools package.
+
+ Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+
+ This file is distributed under the GPL, see file COPYING for details
+
+*/
+
+#include <stdio.h>
+#include <math.h>
+#include <fcntl.h>
+#include <jpeglib.h>
+#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);
+
+ if (scanline)
+ { int y;
+ U8 * js = scanline;
+ for (y=0;y<cinfo.output_height;y++)
+ { jpeg_read_scanlines(&cinfo,&js,1);
+ swf_SetJPEGBitsLines(out,(U8**)&js,1);
+ }
+ free(scanline);
+ }
+
+ swf_SetJPEGBitsFinish(out);
+
+ t = swf_InsertTag(t,ST_DEFINESHAPE);
+
+ swf_ShapeNew(&s);
+ swf_GetMatrix(NULL,&m);
+ m.sx = 20*0x10000;
+ m.sy = 20*0x10000;
+ fs = swf_ShapeAddBitmapFillStyle(s,&m,id,0);
+
+ swf_SetU16(t,id+1); // id
+
+
+ r.xmin = r.ymin = 0;
+ r.xmax = cinfo.output_width*20;
+ r.ymax = cinfo.output_height*20;
+ swf_SetRect(t,&r);
+
+ swf_SetShapeHeader(t,s);
+
+ swf_ShapeSetAll(t,s,0,0,0,fs,0);
+ swf_ShapeSetLine(t,s,r.xmax,0);
+ swf_ShapeSetLine(t,s,0,r.ymax);
+ swf_ShapeSetLine(t,s,-r.xmax,0);
+ swf_ShapeSetLine(t,s,0,-r.ymax);
+
+ swf_ShapeSetEnd(t);
+
+ t = swf_InsertTag(t,ST_REMOVEOBJECT2);
+ swf_SetU16(t,1); // depth
+
+ t = swf_InsertTag(t,ST_PLACEOBJECT2);
+
+ swf_GetMatrix(NULL,&m);
+ m.tx = (swf->movieSize.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_width<width) global.max_image_width = width;
+ if (global.max_image_height<height) global.max_image_height = height;
+
+ jpeg_destroy_decompress(&cinfo);
+ fclose(f);
+
+ return 0;
+}
+
+int args_callback_option(char*arg,char*val)
+{ int res = 0;
+ if (arg[1]) res = -1;
+ else switch (arg[0])
+ { case 'q':
+ if (val) global.quality = atoi(val);
+ if ((global.quality<1)||(global.quality>100))
+ { 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<global.nfiles;i++)
+ { if (VERBOSE(3)) fprintf(stderr,"[%03i] %s (%i%%, 1/%i)\n",i,image[i].filename,image[i].quality,image[i].scale);
+ t = MovieAddFrame(&swf,t,image[i].filename,
+ image[i].quality,
+ image[i].scale,(i*2)+1);
+ free(image[i].filename);
+ }
+ }
+
+ MovieFinish(&swf,t,global.outfile);
+
+ return 0;
+}
+
+
+// Old main routine
+
+/*
+int ConvertJPEG2SWF(char * sname,char * dname,int quality)
+{ RGBA rgb;
+ SWF swf;
+ TAG * t;
+
+ SHAPE * s;
+ SRECT r;
+ MATRIX m;
+ int fs;
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ LPJPEGBITS out;
+ FILE * f;
+ U8 * scanline;
+
+ int handle;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+
+ if ((f=fopen(sname,"rb"))==NULL)
+ { fprintf(stderr,"Read access failed: %s\n",sname);
+ return -1;
+ }
+
+ jpeg_stdio_src(&cinfo,f);
+ jpeg_read_header(&cinfo, TRUE);
+ jpeg_start_decompress(&cinfo);
+
+ memset(&swf,0x00,sizeof(SWF));
+
+ swf.FileVersion = 4;
+ swf.FrameRate = 0x1000;
+ swf.MovieSize.xmax = cinfo.output_width*20;
+ swf.MovieSize.ymax = cinfo.output_height*20;
+
+ printf("dx = %i, dy = %i\n",cinfo.output_width,cinfo.output_height);
+
+ t = swf.FirstTag = InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
+
+ rgb.r = rgb.g = rgb.b = rgb.a = 0x00;
+ SetRGB(t,&rgb);
+
+ t = InsertTag(t,ST_DEFINEBITSJPEG2);
+
+ SetU16(t,1); // 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;y<cinfo.output_height;y++)
+ { jpeg_read_scanlines(&cinfo,&js,1);
+ SetJPEGBitsLines(out,(U8**)&js,1);
+ }
+ free(scanline);
+ }
+
+ SetJPEGBitsFinish(out);
+
+ printf("JPEG Tag-Length: %06x\n",GetDataSize(t));
+
+ t = InsertTag(t,ST_DEFINESHAPE);
+
+ NewShape(&s);
+ GetMatrix(NULL,&m);
+ m.sx = 20*0x10000;
+ m.sy = 20*0x10000;
+ rgb.r = 0xff;
+ fs = ShapeAddBitmapFillStyle(s,&m,1,0);
+// fs = ShapeAddSolidFillStyle(s,&rgb);
+
+ SetU16(t,2); // id
+ SetRect(t,&swf.MovieSize);
+ SetShapeHeader(t,s);
+
+ ShapeSetAll(t,s,0,0,0,fs,0);
+ ShapeSetLine(t,s,swf.MovieSize.xmax,0);
+ ShapeSetLine(t,s,0,swf.MovieSize.ymax);
+ ShapeSetLine(t,s,-swf.MovieSize.xmax,0);
+ ShapeSetLine(t,s,0,-swf.MovieSize.ymax);
+
+ ShapeSetEnd(t);
+
+ t = InsertTag(t,ST_PLACEOBJECT2);
+
+ ObjectPlace(t,2,1,NULL,NULL,NULL);
+
+ t = InsertTag(t,ST_SHOWFRAME);
+
+ t = InsertTag(t,ST_END);
+
+ jpeg_finish_decompress(&cinfo);
+ fclose(f);
+
+ handle = open(dname,O_RDWR|O_CREAT|O_TRUNC,0666);
+ if FAILED(WriteSWF(handle,&swf)) fprintf(stderr,"WriteSWF() failed.\n");
+ close(handle);
+
+ return 0;
+}
+*/
+