* added h.263 support
authorkramm <kramm>
Sat, 2 Aug 2003 12:23:40 +0000 (12:23 +0000)
committerkramm <kramm>
Sat, 2 Aug 2003 12:23:40 +0000 (12:23 +0000)
* removed scaling option
* changed indent to -kr
* merged code with ../lib/modules/swfbits.c

src/jpeg2swf.c

index 397721d..7ce2899 100644 (file)
@@ -5,6 +5,7 @@
    Part of the swftools package.
 
    Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
+   Copyright (c) 2002,2003 Matthias Kramm <kramm@quiss.org>
  
    This file is distributed under the GPL, see file COPYING for details 
 
 #include <fcntl.h>
 #include <jpeglib.h>
 #include "../lib/rfxswf.h"
-#include "../lib/args.h" // not really a header ;-)
+#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;
+struct {
+    int quality;
+    int framerate;
+    int max_image_width;
+    int max_image_height;
+    int force_width;
+    int force_height;
+    int nfiles;
+    int verbose;
+    char *outfile;
+    int mx;
 } global;
 
-struct
-{ char * filename;
-  int scale;
-  int quality;
-} image[MAX_INPUT_FILES];
+typedef struct _image {
+    char *filename;
+    int quality;
+    int width;
+    int height;
+} image_t;
+image_t image[MAX_INPUT_FILES];
 
-TAG * MovieStart(SWF * swf,int framerate,int dx,int dy)
-{ TAG * t;
-  RGBA rgb;
+VIDEOSTREAM stream;
 
-  memset(swf,0x00,sizeof(SWF));
+TAG *MovieStart(SWF * swf, int framerate, int dx, int dy)
+{
+    TAG *t;
+    RGBA rgb;
 
-  swf->fileVersion       = 4;
-  swf->frameRate         = (25600/framerate);
-  swf->movieSize.xmax    = dx*20;
-  swf->movieSize.ymax    = dy*20;
+    memset(swf, 0x00, sizeof(SWF));
 
-  t = swf->firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
+    swf->fileVersion = 4;
+    swf->frameRate = (25600 / framerate);
+    swf->movieSize.xmax = dx * 20;
+    swf->movieSize.ymax = dy * 20;
 
-  rgb.r = rgb.g = rgb.b = rgb.a  = 0x00;
-  swf_SetRGB(t,&rgb);
+    t = swf->firstTag = swf_InsertTag(NULL, ST_SETBACKGROUNDCOLOR);
 
-  return t;
+    rgb.r = rgb.g = rgb.b = rgb.a = 0x00;
+    swf_SetRGB(t, &rgb);
+
+    if (global.mx) {
+       t = swf_InsertTag(t, ST_DEFINEVIDEOSTREAM);
+       swf_SetU16(t, 0xf00d);
+       swf_SetVideoStreamDefine(t, &stream, 65535, dx, dy);
+    }
+
+    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_BINARY|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;
+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_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
+    }
+    if (swf_WriteSWF(handle, swf)<0) 
+           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);
+int getJPEG(char*filename, int* width, int* height, RGBA**pic2)
+{
+    struct jpeg_decompress_struct cinfo;
+    struct jpeg_error_mgr jerr;
+    struct jpeg_source_mgr mgr;
+    int x,y;
+    FILE*f;
+    RGBA*pic,*js;
+    U8*buf;
+
+    if ((f=fopen(filename,"rb"))==NULL) {
+       fprintf(stderr, "rfxswf: file open error\n");
+       return 0;
+    }
 
-  t = swf_InsertTag(t,ST_DEFINEBITSJPEG2);
+    cinfo.err = jpeg_std_error(&jerr);
+    jpeg_create_decompress(&cinfo); 
+    jpeg_stdio_src(&cinfo, f);
+    jpeg_read_header(&cinfo, TRUE);
+    jpeg_start_decompress(&cinfo);
 
-        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<cinfo.output_height;y++)
-             { int x;
-               jpeg_read_scanlines(&cinfo,&js,1);
-               for(x=cinfo.output_width-1;x>=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;y<cinfo.output_height;y++)
-             { jpeg_read_scanlines(&cinfo,&js,1);
-               swf_SetJPEGBitsLines(out,(U8**)&js,1);
-             }
-         }
-          free(scanline);
-        }
-        
-        swf_SetJPEGBitsFinish(out);
+    pic = malloc(cinfo.output_width*cinfo.output_height*sizeof(RGBA));
+    buf = malloc(cinfo.output_width*4);
+    memset(pic, 255, cinfo.output_width*cinfo.output_height*sizeof(RGBA));
+    js = pic;
+
+    *width = cinfo.output_width;
+    *height = cinfo.output_height;
+    
+    for (y=0;y<cinfo.output_height;y++) {
+       int x;
+       jpeg_read_scanlines(&cinfo,&buf,1);
+
+       if(cinfo.out_color_space == JCS_GRAYSCALE) {
+           for(x=0;x<cinfo.output_width;x++) {
+               js[x].r = js[x].g = js[x].b = buf[x];
+           }
+       } else if(cinfo.out_color_space == JCS_RGB) {
+           for (x=0;x<cinfo.output_width;x++)
+           { 
+               js[x].r = buf[x*3+0];
+               js[x].g = buf[x*3+1];
+               js[x].b = buf[x*3+2];
+           }
+       } else if(cinfo.out_color_space == JCS_YCCK) {
+           //FIXME
+           fprintf(stderr, "Error: Can't convert YCCK to RGB.\n");
+           return -1;
+       } else if(cinfo.out_color_space == JCS_YCbCr) {
+           for(x=0;x<cinfo.output_width;x++) {
+               int y = buf[x*3+0];
+               int u = buf[x*3+1];
+               int v = buf[x*3+1];
+               js[x].r = y + ((360*(v-128))>>8);
+               js[x].g = y - ((88*(u-128)+183*(v-128))>>8);
+               js[x].b = y + ((455 * (u-128))>>8);
+           }
+       }
+       else if(cinfo.out_color_space == JCS_CMYK) 
+       { 
+           for(x=0;x<cinfo.output_width;x++) {
+                 int white = 255 - buf[x*4+3];
+                 js[x].r = white - ((buf[x*4]*white)>>8);
+                 js[x].g = white - ((buf[x*4+1]*white)>>8);
+                 js[x].b = white - ((buf[x*4+2]*white)>>8);
+           }
+       }
+       js += cinfo.output_width;
+    }
+
+    jpeg_finish_decompress(&cinfo);
+    jpeg_destroy_decompress(&cinfo);
     
-  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;
+    free(buf);
+    *pic2 = pic;
+    return 1;
 }
 
-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;
-        }
-      }
+
+int frame = 0;
+TAG *MovieAddFrame(SWF * swf, TAG * t, char *sname, int quality, 
+                  int id, int width, int height)
+{
+    SHAPE *s;
+    SRECT r;
+    MATRIX m;
+    int fs;
+
+
+    if(global.mx) {
+       int sizex, sizey;
+       RGBA * pic2;
+       SWFPLACEOBJECT obj;
+       int quant=0;
+       getJPEG(sname, &sizex, &sizey, &pic2);
+       if(sizex != stream.owidth || sizey != stream.oheight) {
+           fprintf(stderr, "All images must have the same dimensions if using -m!");
+           exit(1);
+       }
+
+       t = swf_InsertTag(t, ST_VIDEOFRAME);
+       swf_SetU16(t, 0xf00d);
+       quant = 1+(30-(30*quality)/100);
+       if(!(frame&127)) {
+           swf_SetVideoStreamIFrame(t, &stream, pic2, quant);
+       } else {
+           swf_SetVideoStreamPFrame(t, &stream, pic2, quant);
+       }
+
+       t = swf_InsertTag(t, ST_PLACEOBJECT2);
+       swf_GetPlaceObject(0, &obj);
+       if(frame==0) {
+           obj.depth = 1;
+           obj.id = 0xf00d;
+       } else {
+           obj.depth = 1;
+           obj.move = 1;
+           obj.ratio = frame;
+       }
+       swf_SetPlaceObject(t,&obj);
+
+       t = swf_InsertTag(t, ST_SHOWFRAME);
+    } else {
+       t = swf_InsertTag(t, ST_DEFINEBITSJPEG2);
+       swf_SetU16(t, id);              // id
+       swf_SetJPEGBits(t,sname,quality);
+
+       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 = width * 20;
+       r.ymax = 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) width * 20) / 2;
+       m.ty = (swf->movieSize.ymax - (int) height * 20) / 2;
+       swf_ObjectPlace(t, id + 1, 1, &m, NULL, NULL);
+
+       t = swf_InsertTag(t, ST_SHOWFRAME);
     }
-  }
-  
-  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;
+    frame++;
+
+    return t;
+}
+
+int CheckInputFile(image_t* i, 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);
+
+    width = cinfo.image_width;
     height = cinfo.image_height;
-  }
 
-  // Get image dimensions
+    i->width = width;
+    i->height = height;
 
-  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);
+    // Get image dimensions
 
-  return 0;
-}
+    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);
 
-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) {
+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 '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 'm':
+           global.mx = 1;
+           return 0;
+
+       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"},
+{"m", "mx"},
+{"r", "rate"},
+{"v", "verbose"},
+{"X", "width"},
+{"Y", "height"},
+{"V", "version"},
+};
+
+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);
+int args_callback_command(char *arg, char *next)       // actually used as filename
+{
+    char *s;
+    image_t* i = &image[global.nfiles];
+    if (CheckInputFile(i, arg, &s) < 0) {
+       if (VERBOSE(1))
+           fprintf(stderr, "Unable to open input file: %s\n", arg);
+       free(s);
+    } else {
+       i->filename = s;
+       i->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;
+    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");
+void args_callback_usage(char *name)
+{
+    printf
+       ("Usage: %s  [-options [value]] imagefiles[.jpg]|[.jpeg] [...]\n",
+        name);
+    printf
+       ("-o outputfile       --output   explicitly specify output file. (otherwise, output.swf will be used)\n");
+    printf
+       ("-m                  --mx       Use Flash MX H.263 compression (use for correlated images)\n");
+    printf
+       ("-q quality          --quality  Set compression quality (1-100, 1=worst, 100=best)\n");
+    printf
+       ("-r framerate        --rate     Set movie framerate (100/sec)\n");
+    printf
+       ("-o outputfile       --output   Set name for SWF output file\n");
+    printf
+       ("-X pixel            --width    Force movie width to pixel (default: autodetect)\n");
+    printf
+       ("-Y pixel            --height   Force movie height to pixel (default: autodetect)\n");
+    printf
+       ("-v level            --verbose  Set verbose level (0=quiet, 1=default, 2=debug)\n");
+    printf
+       ("-V                  --version  Print version information and exit\n");
+    printf
+       ("The following options can be set independently for each image: -q -s\n");
 }
 
 
-int main(int argc, char ** argv)
-{ SWF swf;
-  TAG * t;
+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);
-    }
-  }
+    memset(&global, 0x00, sizeof(global));
 
-  MovieFinish(&swf,t,global.outfile);
+    global.quality = 60;
+    global.framerate = 100;
+    global.verbose = 1;
 
-  return 0;
-}
+    processargs(argc, argv);
 
+    if (VERBOSE(2))
+       fprintf(stderr, "Processing %i file(s)...\n", global.nfiles);
 
-// 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_BINARY|O_RDWR|O_CREAT|O_TRUNC,0666);
-  if FAILED(WriteSWF(handle,&swf)) fprintf(stderr,"WriteSWF() failed.\n");
-  close(handle);
-
-  return 0;
-}
-*/
+    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);
+           t = MovieAddFrame(&swf, t, image[i].filename, image[i].quality,
+                             (i * 2) + 1, 
+                             image[i].width, image[i].height);
+           free(image[i].filename);
+       }
+    }
+
+    MovieFinish(&swf, t, global.outfile);
+
+    return 0;
+}