prefix button names with link type for -s linknameurl
[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 #include "../lib/devices/rescale.h"
14
15 static struct options_t options[] = {
16 {"h", "help"},
17 {"o", "output"},
18 {"p", "pages"},
19 {"l", "legacy"},
20 {"V", "version"},
21 {"X", "width"},
22 {"Y", "height"},
23 {0,0}
24 };
25
26 static int ng = 1;
27 static char*filename = 0;
28 static char*outputname = "output.png";
29 static int quantize = 0;
30 static char*pagerange = 0;
31
32 static int width = 0;
33 static int height = 0;
34
35 typedef struct _parameter {
36     const char*name;
37     const char*value;
38     struct _parameter*next;
39 } parameter_t;
40
41 parameter_t*params = 0;
42
43 int args_callback_option(char*name,char*val)
44 {
45     if(!strcmp(name, "V")) {
46         printf("swfrender - part of %s %s\n", PACKAGE, VERSION);
47         exit(0);
48     } else if(!strcmp(name, "o")) {
49         outputname = strdup(val);
50         return 1;
51     } else if(!strcmp(name, "l")) {
52         ng = 0;
53         return 0;
54     } else if(!strcmp(name, "q")) {
55         quantize = 1;
56         return 0;
57     } else if(!strcmp(name, "p")) {
58         pagerange = val;
59         return 1;
60     } else if(!strcmp(name, "s")) {
61         char*s = strdup(val);
62         char*c = strchr(s, '=');
63         parameter_t*p = malloc(sizeof(parameter_t));
64         p->next = params;
65         params = p;
66         if(c && *c && c[1])  {
67             *c = 0;
68             c++;
69             p->name = s;
70             p->value = s;
71         } else {
72             p->name = s;
73             p->value = "1";
74         }
75         return 1;
76     } else if(!strcmp(name, "X")) {
77         width = atoi(val);
78         return 1;
79     } else if(!strcmp(name, "Y")) {
80         height = atoi(val);
81         return 1;
82     } else {
83         printf("Unknown option: -%s\n", name);
84         exit(1);
85     }
86
87     return 0;
88 }
89 int args_callback_longoption(char*name,char*val)
90 {
91     return args_long2shortoption(options, name, val);
92 }
93 void args_callback_usage(char *name)
94 {
95     printf("\n");
96     printf("Usage: %s file.swf [-o output.png]\n", name);
97     printf("\n");
98     printf("-h , --help                    Print short help message and exit\n");
99     printf("-l , --legacy                  Use old rendering framework\n");
100     printf("-o , --output                  Output file (default: output.png)\n");
101     printf("\n");
102 }
103 int args_callback_command(char*name,char*val)
104 {
105     if(filename) {
106         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
107                  filename, name);
108     }
109     filename = name;
110     return 0;
111 }
112
113
114
115 int main(int argn, char*argv[])
116 {
117     SWF swf;
118     int fi;
119
120     processargs(argn, argv);
121
122     if(!filename) {
123         fprintf(stderr, "You must supply a filename.\n");
124         return 1;
125     }
126
127     if(!ng) {
128         fi = open(filename, O_RDONLY|O_BINARY);
129         if (fi<=0) { 
130             fprintf(stderr,"Couldn't open %s\n", filename);
131             perror(filename);
132             exit(1);
133         }
134         if(swf_ReadSWF(fi,&swf)<0) { 
135             fprintf(stderr,"%s is not a valid SWF file or contains errors.\n",argv[1]);
136             close(fi);
137         }
138         assert(swf.movieSize.xmax > swf.movieSize.xmin && swf.movieSize.ymax > swf.movieSize.ymin);
139         RENDERBUF buf;
140         swf_Render_Init(&buf, 0,0, (swf.movieSize.xmax - swf.movieSize.xmin) / 20,
141                                    (swf.movieSize.ymax - swf.movieSize.ymin) / 20, 2, 1);
142         swf_RenderSWF(&buf, &swf);
143         RGBA* img = swf_Render(&buf);
144         if(quantize)
145             writePalettePNG(outputname, (unsigned char*)img, buf.width, buf.height);
146         else
147             writePNG(outputname, (unsigned char*)img, buf.width, buf.height);
148         swf_Render_Delete(&buf);
149     } else {
150         parameter_t*p;
151
152         gfxsource_t*src = gfxsource_swf_create();
153         for(p=params;p;p=p->next) {
154             src->set_parameter(src, p->name, p->value);
155         }
156         gfxdocument_t*doc = src->open(src, filename);
157         for(p=params;p;p=p->next) {
158             doc->set_parameter(doc, p->name, p->value);
159         }
160         if(!doc) {
161             fprintf(stderr,"Couldn't open %s\n", filename);
162             exit(1);
163         }
164         gfxdevice_t dev2,*dev=&dev2;
165         gfxdevice_render_init(dev);
166         dev->setparameter(dev, "antialise", "4");
167         if(quantize) {
168             dev->setparameter(dev, "palette", "1");
169         }
170         if(width || height) {
171             dev = gfxdevice_rescale_new(dev, width, height, 0);
172         }
173         for(p=params;p;p=p->next) {
174             dev->setparameter(dev, p->name, p->value);
175         }
176
177         int t;
178         for(t=1;t<=doc->num_pages;t++) {
179             if(!is_in_range(t, pagerange))
180                 continue;
181             gfxpage_t* page = doc->getpage(doc, t);
182             dev->startpage(dev, page->width, page->height);
183             page->render(page, dev);
184             dev->endpage(dev);
185             page->destroy(page);
186             break;
187         }
188         gfxresult_t*result = dev->finish(dev);
189         if(result) {
190             if(result->save(result, outputname) < 0) {
191                 exit(1);
192             }
193             result->destroy(result);
194         }
195         doc->destroy(doc);
196     }
197     return 0;
198 }
199