bugfix in rescale filter
[swftools.git] / src / swfrender.c
blob87a8b32ad5752b9e1b5b746200598af1f3dbb4ba
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"
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}
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;
32 static int width = 0;
33 static int height = 0;
35 typedef struct _parameter {
36 const char*name;
37 const char*value;
38 struct _parameter*next;
39 } parameter_t;
41 parameter_t*params = 0;
43 int args_callback_option(char*name,char*val)
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";
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);
87 return 0;
89 int args_callback_longoption(char*name,char*val)
91 return args_long2shortoption(options, name, val);
93 void args_callback_usage(char *name)
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");
103 int args_callback_command(char*name,char*val)
105 if(filename) {
106 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
107 filename, name);
109 filename = name;
110 return 0;
115 int main(int argn, char*argv[])
117 SWF swf;
118 int fi;
120 processargs(argn, argv);
122 if(!filename) {
123 fprintf(stderr, "You must supply a filename.\n");
124 return 1;
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);
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);
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 png_write_palette_based_2(outputname, (unsigned char*)img, buf.width, buf.height);
146 else
147 png_write(outputname, (unsigned char*)img, buf.width, buf.height);
148 swf_Render_Delete(&buf);
149 } else {
150 parameter_t*p;
152 gfxsource_t*src = gfxsource_swf_create();
153 for(p=params;p;p=p->next) {
154 src->setparameter(src, p->name, p->value);
156 gfxdocument_t*doc = src->open(src, filename);
157 for(p=params;p;p=p->next) {
158 doc->setparameter(doc, p->name, p->value);
160 if(!doc) {
161 fprintf(stderr,"Couldn't open %s\n", filename);
162 exit(1);
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");
170 if(width || height) {
171 dev = gfxdevice_rescale_new(dev, width, height, 0);
173 for(p=params;p;p=p->next) {
174 dev->setparameter(dev, p->name, p->value);
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;
188 gfxresult_t*result = dev->finish(dev);
189 if(result) {
190 if(result->save(result, outputname) < 0) {
191 exit(1);
193 result->destroy(result);
195 doc->destroy(doc);
197 return 0;