11d812b23f5f8123a6ac7d4e7d493f4746e7d192
[swftools.git] / lib / example / avi2swf.cc
1 /* avi2swf.cc
2    Convert avi movie files into swf.
3    As soon as there's an algorithm implemented for writing the
4    data directly to disk, this file should maybe go to ../src.
5
6    Part of the swftools package.
7    
8    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
9
10    This file is distributed under the GPL, see file COPYING for details */
11
12 #include <stdio.h>
13 #include <fcntl.h>
14 extern "C" {
15 #include "../rfxswf.h"
16 #include "../args.h"
17 }
18 #include "avifile.h"
19 #include "aviplay.h"
20
21 char * filename = 0;
22 char * outputfilename = "output.swf";
23
24 struct options_t options[] =
25 {
26  {"v","verbose"},
27  {"o","output"},
28  {"V","version"},
29  {0,0}
30 };
31
32 int args_callback_option(char*name,char*val)
33 {
34     if(!strcmp(name, "V")) {
35         printf("avi2swf - part of %s %s\n", PACKAGE, VERSION);
36         exit(0);
37     } else 
38     if(!strcmp(name, "o")) {
39         outputfilename = val;
40         return 1;
41     }
42 }
43 int args_callback_longoption(char*name,char*val)
44 {
45     return args_long2shortoption(options, name, val);
46 }
47 void args_callback_usage(char*name)
48 {    
49     printf("\nUsage: %s file.swf\n", name);
50     printf("\t-h , --help\t\t Print help and exit\n");
51     printf("\t-o , --output=filename\t Specify output filename\n"); 
52     printf("\t-V , --version\t\t Print program version and exit\n");
53     exit(0);
54 }
55 int args_callback_command(char*name,char*val)
56 {
57     if(filename) {
58         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
59                  filename, name);
60     }
61     filename = name;
62     return 0;
63 }
64
65 SWF swf;
66 TAG*tag;
67
68 int main (int argc,char ** argv)
69 { int f;
70   IAviReadFile* player;
71   IAviReadStream* astream;
72   IAviReadStream* vstream;
73   MainAVIHeader head;
74   SRECT r;
75   memset(&swf, 0, sizeof(swf));
76
77   processargs(argc, argv);
78   if(!filename)
79       exit(0);
80
81   player = CreateIAviReadFile(filename);    
82   player->GetFileHeader(&head);
83   printf("fps: %d\n", 1000000/head.dwMicroSecPerFrame);
84   printf("frames: %d\n", head.dwTotalFrames);
85   printf("streams: %d\n", head.dwStreams);
86   printf("streams: %d\n", player->StreamCount());
87   printf("width: %d\n", head.dwWidth);
88   printf("height: %d\n", head.dwHeight);
89   
90   astream = player->GetStream(0, AviStream::Audio);
91   vstream = player->GetStream(0, AviStream::Video);
92
93   vstream -> StartStreaming();
94   
95   swf.frameRate = (int)(1000000.0/head.dwMicroSecPerFrame*256);
96   swf.fileVersion = 4;
97   r.xmin = 0;
98   r.ymin = 0;
99   r.xmax = head.dwWidth*20;
100   r.ymax = head.dwHeight*20;
101   swf.movieSize = r;
102   tag = swf_InsertTag(NULL, ST_SETBACKGROUNDCOLOR);
103   swf.firstTag = tag;
104   swf_SetU8(tag,0); //black
105   swf_SetU8(tag,0);
106   swf_SetU8(tag,0);
107
108   U8*newdata = (U8*)malloc((head.dwWidth+3) * head.dwHeight * 4);
109
110   int frame = 0;
111
112   while(1) {
113     if(vstream->ReadFrame()<0) {
114         printf("\n");
115         break;
116     }
117     printf("\rconvert frame %d",frame);
118     fflush(stdout);
119     CImage*img = vstream->GetFrame();
120     img->ToRGB();
121     U8* data = img->data();
122     int width = img->width();
123     int bpp = img->bpp();
124     int width4 = width*4;
125     int height = img->height();
126     int x,y;
127     int fs,ls;
128     SHAPE*s;
129     MATRIX m;
130     SRECT r;
131     RGBA rgb;
132
133     if(frame!=0) {
134         tag = swf_InsertTag(tag, ST_REMOVEOBJECT2);
135         swf_SetU16(tag, 1); //depth
136     }
137
138     /* todo: dynamically decide whether to generate jpeg/lossless
139        bitmaps, (using transparency to modify the previous 
140        picture), and which jpeg compression depth to use.
141        (btw: Are there video frame transitions which can
142         reasonably approximated by shapes?)
143      */
144
145     int type = 1;
146     if(type == 0) {
147         tag = swf_InsertTag(tag, ST_DEFINEBITSLOSSLESS);
148         swf_SetU16(tag, frame*2);
149         for(y=0;y<height;y++) {
150             U8*nd = &newdata[width4*y];
151             data = img->at(y);
152             for(x=0;x<width;x++) {
153                 nd[0]=255;
154                 nd[3]=data[0];
155                 nd[2]=data[1];
156                 nd[1]=data[2];
157                 nd+=4;
158                 data+=3;
159             }
160         }
161         swf_SetLosslessBits(tag,width,height,newdata,BMF_32BIT);
162     } else 
163     if(type == 1) {
164         tag = swf_InsertTag(tag, ST_DEFINEBITSJPEG2);
165         swf_SetU16(tag, frame*2);
166         JPEGBITS * jb = swf_SetJPEGBitsStart(tag,width,height,10);
167         for(y=0;y<height;y++) {
168             U8*nd = newdata;
169             data = img->at(y);
170             for(x=0;x<width;x++) {
171                 nd[0] = data[2];
172                 nd[1] = data[1];
173                 nd[2] = data[0];
174                 nd+=3;
175                 data+=3;
176             }
177             swf_SetJPEGBitsLine(jb,newdata);
178         }
179         swf_SetJPEGBitsFinish(jb);
180     }
181
182     tag = swf_InsertTag(tag, ST_DEFINESHAPE);
183     swf_ShapeNew(&s);
184     rgb.b = rgb.g = rgb.r = 0xff;
185     ls = swf_ShapeAddLineStyle(s,20,&rgb);  
186     swf_GetMatrix(NULL,&m);
187     m.sx = 20*65536;
188     m.sy = 20*65536;
189
190     fs = swf_ShapeAddBitmapFillStyle(s,&m,frame*2,0);
191     swf_SetU16(tag ,frame*2+1);   // ID   
192     r.xmin = 0;
193     r.ymin = 0;
194     r.xmax = width*20;
195     r.ymax = height*20;
196     swf_SetRect(tag,&r);
197
198     swf_SetShapeStyles(tag,s);
199     swf_ShapeCountBits(s,NULL,NULL);
200     swf_SetShapeBits(tag,s);
201
202     swf_ShapeSetAll(tag,s,0,0,ls,fs,0);
203
204     swf_ShapeSetLine(tag,s,width*20,0);
205     swf_ShapeSetLine(tag,s,0,height*20);
206     swf_ShapeSetLine(tag,s,-width*20,0);
207     swf_ShapeSetLine(tag,s,0,-height*20);
208     swf_ShapeSetEnd(tag);
209
210     tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
211         swf_ObjectPlace(tag,frame*2+1,1,0,0,0);
212
213     tag = swf_InsertTag(tag, ST_SHOWFRAME);
214
215     frame++;
216     if(frame == 200)
217         break;
218   }
219   free(newdata);
220   
221   tag = swf_InsertTag(tag, ST_END);
222
223   f = open(outputfilename,O_WRONLY|O_CREAT|O_TRUNC, 0644);
224   if FAILED(swf_WriteSWF(f,&swf)) fprintf(stderr,"WriteSWF() failed.\n");
225   close(f);
226
227   swf_FreeTags(&swf);                       // cleanup
228
229   return 0;
230 }
231