--- /dev/null
+/* 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