3 JPEG to SWF converter tool
5 Part of the swftools package.
7 Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
9 This file is distributed under the GPL, see file COPYING for details
17 #include "../lib/rfxswf.h"
18 #include "../lib/args.h" // not really a header ;-)
20 #define MAX_INPUT_FILES 1024
21 #define VERBOSE(x) (global.verbose>=x)
32 char * files[MAX_INPUT_FILES];
36 TAG * MovieStart(SWF * swf,int framerate,int dx,int dy)
40 memset(swf,0x00,sizeof(SWF));
43 swf->frameRate = (25600/framerate);
44 swf->movieSize.xmax = dx*20;
45 swf->movieSize.ymax = dy*20;
47 t = swf->firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
49 rgb.r = rgb.g = rgb.b = rgb.a = 0x00;
55 int MovieFinish(SWF * swf,TAG * t,char * sname)
56 { int handle, so = fileno(stdout);
57 t = swf_InsertTag(t,ST_END);
59 if ((!isatty(so))&&(!sname)) handle = so;
61 { if (!sname) sname = "out.swf";
62 handle = open(sname,O_RDWR|O_CREAT|O_TRUNC,0666);
64 if FAILED(swf_WriteSWF(handle,swf)) if (VERBOSE(1)) fprintf(stderr,"Unable to write output file: %s\n",sname);
65 if (handle!=so) close(handle);
71 TAG * MovieAddFrame(SWF * swf,TAG * t,char * sname,int quality,int id)
77 struct jpeg_decompress_struct cinfo;
78 struct jpeg_error_mgr jerr;
83 if ((f=fopen(sname,"rb"))==NULL)
84 { if (VERBOSE(1)) fprintf(stderr,"Read access failed: %s\n",sname);
88 cinfo.err = jpeg_std_error(&jerr);
89 jpeg_create_decompress(&cinfo);
90 jpeg_stdio_src(&cinfo,f);
91 jpeg_read_header(&cinfo, TRUE);
92 jpeg_start_decompress(&cinfo);
94 t = swf_InsertTag(t,ST_DEFINEBITSJPEG2);
96 swf_SetU16(t,id); // id
98 out = swf_SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality);
99 scanline = (U8*)malloc(4*cinfo.output_width);
104 for (y=0;y<cinfo.output_height;y++)
105 { jpeg_read_scanlines(&cinfo,&js,1);
106 swf_SetJPEGBitsLines(out,(U8**)&js,1);
111 swf_SetJPEGBitsFinish(out);
113 t = swf_InsertTag(t,ST_DEFINESHAPE);
116 swf_GetMatrix(NULL,&m);
119 fs = swf_ShapeAddBitmapFillStyle(s,&m,id,0);
121 swf_SetU16(t,id+1); // id
125 r.xmax = cinfo.output_width*20;
126 r.ymax = cinfo.output_height*20;
129 swf_SetShapeHeader(t,s);
131 swf_ShapeSetAll(t,s,0,0,0,fs,0);
132 swf_ShapeSetLine(t,s,r.xmax,0);
133 swf_ShapeSetLine(t,s,0,r.ymax);
134 swf_ShapeSetLine(t,s,-r.xmax,0);
135 swf_ShapeSetLine(t,s,0,-r.ymax);
139 t = swf_InsertTag(t,ST_REMOVEOBJECT2);
140 swf_SetU16(t,1); // depth
142 t = swf_InsertTag(t,ST_PLACEOBJECT2);
144 swf_GetMatrix(NULL,&m);
145 m.tx = (swf->movieSize.xmax-(int)cinfo.output_width*20)/2;
146 m.ty = (swf->movieSize.ymax-(int)cinfo.output_height*20)/2;
147 swf_ObjectPlace(t,id+1,1,&m,NULL,NULL);
149 t = swf_InsertTag(t,ST_SHOWFRAME);
151 jpeg_finish_decompress(&cinfo);
157 int CheckInputFile(char * fname,char ** realname)
158 { struct jpeg_decompress_struct cinfo;
159 struct jpeg_error_mgr jerr;
161 char * s = malloc(strlen(fname)+5);
167 // Check whether file exists (with typical extensions)
169 if ((f=fopen(s,"rb"))==NULL)
170 { sprintf(s,"%s.jpg",fname);
171 if ((f=fopen(s,"rb"))==NULL)
172 { sprintf(s,"%s.jpeg",fname);
173 if ((f=fopen(s,"rb"))==NULL)
174 { sprintf(s,"%s.JPG",fname);
175 if ((f=fopen(s,"rb"))==NULL)
176 { sprintf(s,"%s.JPEG",fname);
177 if ((f=fopen(s,"rb"))==NULL)
184 cinfo.err = jpeg_std_error(&jerr);
185 jpeg_create_decompress(&cinfo);
186 jpeg_stdio_src(&cinfo,f);
187 jpeg_read_header(&cinfo, TRUE);
189 // Get image dimensions
191 if (global.max_image_width<cinfo.image_width) global.max_image_width = cinfo.image_width;
192 if (global.max_image_height<cinfo.image_height) global.max_image_height = cinfo.image_height;
194 jpeg_destroy_decompress(&cinfo);
200 int args_callback_option(char*arg,char*val)
202 if (arg[1]) res = -1;
205 if (val) global.quality = atoi(val);
206 if ((global.quality<1)||(global.quality>100))
207 { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid quality between 1 and 100.\n");
214 if (val) global.framerate = atoi(val);
215 if ((global.framerate<1)||(global.framerate>5000))
216 { if (VERBOSE(1)) fprintf(stderr,"Error: You must specify a valid framerate between 1 and 10000.\n");
223 if (val) global.outfile = val; res = 1; break;
226 if (val) global.verbose = atoi(val); res = 1; break;
229 if (val) global.force_width = atoi(val); res = 1; break;
232 if (val) global.force_height = atoi(val); res = 1; break;
235 printf("jpeg2swf - part of %s %s\n", PACKAGE, VERSION);exit(0);
243 { if (VERBOSE(1)) fprintf(stderr,"Unknown option: -v%s\n",arg);
249 struct options_t options[] =
259 int args_callback_longoption(char*name,char*val) {
260 return args_long2shortoption(options, name, val);
263 int args_callback_command(char*arg,char*next) // actually used as filename
265 if (CheckInputFile(arg,&s)<0)
266 { if (VERBOSE(1)) fprintf(stderr, "Unable to open input file: %s\n",arg);
270 { global.files[global.nfiles] = s;
272 if (global.nfiles>=MAX_INPUT_FILES)
273 { if (VERBOSE(1)) fprintf(stderr, "Error: Too many input files.\n");
280 void args_callback_usage(char*name)
281 { fprintf(stderr,"Usage: %s imagefiles[.jpg]|[.jpeg] [...] [-options [value]]\n",name);
282 fprintf(stderr,"-q quality (quality) Set JPEG compression quality (1-100)\n");
283 fprintf(stderr,"-r framerate (rate) Set movie framerate (100/sec)\n");
284 fprintf(stderr,"-o outputfile (output) Set name for SWF output file\n");
285 fprintf(stderr,"-v level (verbose) Set verbose level (0=quiet, 1=default, 2=debug)\n");
286 fprintf(stderr,"-X pixel (width) Force movie width to scale (default: autodetect)\n");
287 fprintf(stderr,"-Y pixel (height) Force movie height to scale (default: autodetect)\n");
288 fprintf(stderr,"-V (version) Print version information and exit\n");
292 int main(int argc, char ** argv)
296 memset(&global,0x00,sizeof(global));
299 global.framerate = 100;
302 processargs(argc, argv);
304 if (VERBOSE(2)) fprintf(stderr,"Processing %i file(s)...\n",global.nfiles);
306 t = MovieStart(&swf,global.framerate,
307 global.force_width?global.force_width:global.max_image_width,
308 global.force_height?global.force_height:global.max_image_height);
311 for (i=0;i<global.nfiles;i++)
312 { if (VERBOSE(3)) fprintf(stderr,"[%03i] %s\n",i,global.files[i]);
313 t = MovieAddFrame(&swf,t,global.files[i],global.quality,(i*2)+1);
314 free(global.files[i]);
318 MovieFinish(&swf,t,global.outfile);
327 int ConvertJPEG2SWF(char * sname,char * dname,int quality)
337 struct jpeg_decompress_struct cinfo;
338 struct jpeg_error_mgr jerr;
345 cinfo.err = jpeg_std_error(&jerr);
346 jpeg_create_decompress(&cinfo);
348 if ((f=fopen(sname,"rb"))==NULL)
349 { fprintf(stderr,"Read access failed: %s\n",sname);
353 jpeg_stdio_src(&cinfo,f);
354 jpeg_read_header(&cinfo, TRUE);
355 jpeg_start_decompress(&cinfo);
357 memset(&swf,0x00,sizeof(SWF));
360 swf.FrameRate = 0x1000;
361 swf.MovieSize.xmax = cinfo.output_width*20;
362 swf.MovieSize.ymax = cinfo.output_height*20;
364 printf("dx = %i, dy = %i\n",cinfo.output_width,cinfo.output_height);
366 t = swf.FirstTag = InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
368 rgb.r = rgb.g = rgb.b = rgb.a = 0x00;
371 t = InsertTag(t,ST_DEFINEBITSJPEG2);
375 out = SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality);
376 scanline = (U8*)malloc(4*cinfo.output_width);
381 for (y=0;y<cinfo.output_height;y++)
382 { jpeg_read_scanlines(&cinfo,&js,1);
383 SetJPEGBitsLines(out,(U8**)&js,1);
388 SetJPEGBitsFinish(out);
390 printf("JPEG Tag-Length: %06x\n",GetDataSize(t));
392 t = InsertTag(t,ST_DEFINESHAPE);
399 fs = ShapeAddBitmapFillStyle(s,&m,1,0);
400 // fs = ShapeAddSolidFillStyle(s,&rgb);
403 SetRect(t,&swf.MovieSize);
406 ShapeSetAll(t,s,0,0,0,fs,0);
407 ShapeSetLine(t,s,swf.MovieSize.xmax,0);
408 ShapeSetLine(t,s,0,swf.MovieSize.ymax);
409 ShapeSetLine(t,s,-swf.MovieSize.xmax,0);
410 ShapeSetLine(t,s,0,-swf.MovieSize.ymax);
414 t = InsertTag(t,ST_PLACEOBJECT2);
416 ObjectPlace(t,2,1,NULL,NULL,NULL);
418 t = InsertTag(t,ST_SHOWFRAME);
420 t = InsertTag(t,ST_END);
422 jpeg_finish_decompress(&cinfo);
425 handle = open(dname,O_RDWR|O_CREAT|O_TRUNC,0666);
426 if FAILED(WriteSWF(handle,&swf)) fprintf(stderr,"WriteSWF() failed.\n");