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