9362fded585fb103d395e80d4efc935d6abd4d8c
[swftools.git] / src / swfrender.c
1 #include "../config.h"
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <assert.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include "../lib/rfxswf.h"
8 #include "../lib/png.h"
9 #include "../lib/args.h"
10 #include "../lib/gfxsource.h"
11 #include "../lib/readers/swf.h"
12 #include "../lib/devices/render.h"
13
14 static struct options_t options[] = {
15 {"h", "help"},
16 {"o", "output"},
17 {"l", "legacy"},
18 {"V", "version"},
19 {"X", "width"},
20 {"Y", "height"},
21 {0,0}
22 };
23
24 static int ng = 1;
25 static char*filename = 0;
26 static char*outputname = "output.png";
27 static int quantize = 0;
28
29 static int width = 0;
30 static int height = 0;
31
32 int args_callback_option(char*name,char*val)
33 {
34     if(!strcmp(name, "V")) {
35         printf("swfrender - part of %s %s\n", PACKAGE, VERSION);
36         exit(0);
37     } else if(!strcmp(name, "o")) {
38         outputname = strdup(val);
39         return 1;
40     } else if(!strcmp(name, "l")) {
41         ng = 0;
42         return 0;
43     } else if(!strcmp(name, "q")) {
44         quantize = 1;
45         return 0;
46     } else if(!strcmp(name, "X")) {
47         width = atoi(val);
48         return 1;
49     } else if(!strcmp(name, "Y")) {
50         height = atoi(val);
51         return 1;
52     } else {
53         printf("Unknown option: -%s\n", name);
54         exit(1);
55     }
56
57     return 0;
58 }
59 int args_callback_longoption(char*name,char*val)
60 {
61     return args_long2shortoption(options, name, val);
62 }
63 void args_callback_usage(char *name)
64 {
65     printf("\n");
66     printf("Usage: %s file.swf [-o output.png]\n", name);
67     printf("\n");
68     printf("-h , --help                    Print short help message and exit\n");
69     printf("-l , --legacy                  Use old rendering framework\n");
70     printf("-o , --output                  Output file (default: output.png)\n");
71     printf("\n");
72 }
73 int args_callback_command(char*name,char*val)
74 {
75     if(filename) {
76         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
77                  filename, name);
78     }
79     filename = name;
80     return 0;
81 }
82
83
84
85 int main(int argn, char*argv[])
86 {
87     SWF swf;
88     int fi;
89
90     processargs(argn, argv);
91
92     if(!filename) {
93         fprintf(stderr, "You must supply a filename.\n");
94         return 1;
95     }
96
97     if(!ng) {
98         fi = open(filename, O_RDONLY|O_BINARY);
99         if (fi<=0) { 
100             fprintf(stderr,"Couldn't open %s\n", filename);
101             perror(argv[1]);
102             exit(1);
103         }
104         if(swf_ReadSWF(fi,&swf)<0) { 
105             fprintf(stderr,"%s is not a valid SWF file or contains errors.\n",argv[1]);
106             close(fi);
107         }
108         RENDERBUF buf;
109         swf_Render_Init(&buf, 0,0, (swf.movieSize.xmax - swf.movieSize.xmin) / 20,
110                                    (swf.movieSize.ymax - swf.movieSize.ymin) / 20, 2, 1);
111         swf_RenderSWF(&buf, &swf);
112         RGBA* img = swf_Render(&buf);
113         if(quantize)
114             writePalettePNG(outputname, (unsigned char*)img, buf.width, buf.height);
115         else
116             writePNG(outputname, (unsigned char*)img, buf.width, buf.height);
117         swf_Render_Delete(&buf);
118     } else {
119         gfxsource_t*src = gfxsource_swf_create();
120         gfxdocument_t*doc = src->open(src, filename);
121         if(!doc) {
122             fprintf(stderr,"Couldn't open %s\n", filename);
123             exit(1);
124         }
125         gfxdevice_t dev2,*dev=&dev2;
126         gfxdevice_render_init(dev);
127         if(quantize) {
128             dev->setparameter(dev, "palette", "1");
129         }
130         if(width || height) {
131             dev = gfxdevice_rescale_new(dev, width, height, 0);
132         }
133
134         int t;
135         for(t=1;t<=doc->num_pages;t++) {
136             gfxpage_t* page = doc->getpage(doc, t);
137             dev->startpage(dev, page->width, page->height);
138             page->render(page, dev);
139             dev->endpage(dev);
140             page->destroy(page);
141             break;
142         }
143         gfxresult_t*result = dev->finish(dev);
144         if(result) {
145             if(result->save(result, outputname) < 0) {
146                 exit(1);
147             }
148             result->destroy(result);
149         }
150         doc->destroy(doc);
151     }
152     return 0;
153 }
154