Initial revision
[swftools.git] / pdf2swf / pdf2swf.cc
1 /* pdf2swf.cc
2    main routine for pdf2swf(1)
3
4    Part of the swftools package.
5    
6    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org> 
7
8    This file is distributed under the GPL, see file COPYING for details */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include "../config.h"
15 #include "args.h"
16 #include "pdfswf.h"
17 #include "t1lib.h"
18 extern "C" {
19 #include "log.h"
20 }
21
22 static char * outputname = 0;
23 static int loglevel = 3;
24 static char * pagerange = 0;
25 static char * filename = 0;
26 static char * password = 0;
27
28 int args_callback_option(char*name,char*val) {
29     if (!strcmp(name, "o"))
30     {
31         outputname = val;
32         return 1;
33     }
34     else if (!strcmp(name, "v"))
35     {
36         loglevel ++;
37         return 0;
38     }
39     else if (name[0]=='p')
40     {
41         /* check whether the page range follows the p directly, like 
42            in -p1,2 */
43         do {
44             name++;
45         } while(*name == 32 || *name == 13 || *name == 10 || *name == '\t');
46
47         if(*name) {
48             pagerange = name;
49             return 0;
50         } 
51         pagerange = val;        
52         return 1;
53     }
54     else if (!strcmp(name, "P"))
55     {
56         password = val;
57         return 1;
58     }
59     else if (!strcmp(name, "V"))
60     {   
61         printf("pdf2swf - part of %s %s\n", PACKAGE, VERSION);
62         exit(0);
63     }
64     else 
65     {
66         fprintf(stderr, "Unknown option: -%s\n", name);
67         exit(1);
68     }
69     return 0;
70 }
71
72 struct options_t
73 {
74     char shortoption;
75     char*longoption;
76 } options[] =
77 {{'o',"output"},
78  {'V',"version"},
79  {'p',"pages"}
80 };
81
82 int args_callback_longoption(char*name,char*val) {
83     int t;
84     char*equal = strchr(name,'=');
85     if (equal) {
86         *equal = 0;
87         equal++;
88     }
89     for(t=0;t<sizeof(options)/sizeof(struct options_t);t++) {
90         if(!strcmp(options[t].longoption, name)) {
91                 char*tmp = (char*)malloc(strlen(equal)+strlen(name)+2);
92                 tmp[0] = options[t].shortoption;
93                 tmp[1] = 0;
94                 if(equal) {
95                     strcpy(&tmp[1], equal);
96                 }
97                 return args_callback_option(tmp,val);
98         }
99     }
100     fprintf(stderr, "Unknown option: %s\n", name);
101     exit(1);
102 }
103
104 int args_callback_command(char*name, char*val) {
105     if (!filename) 
106         filename = name;
107     else {
108         if(outputname)
109         {
110              fprintf(stderr, "Error: Do you want the output to go to %s or to %s?", 
111                      outputname, name);
112              exit(1);
113         }
114         outputname = name;
115     }
116     return 0;
117 }
118
119 void args_callback_usage(char*name)
120 {
121     printf("Usage: %s [-p range] [-P password] input.pdf [output.swf]\n", name);
122     printf("\n");
123     printf("-p range            (range) Convert only pages in range\n");
124     printf("-P password         (password) Use password for deciphering the pdf\n");
125     printf("\n");
126 }
127
128 /* check whether the value t is in a given range.
129   examples: 3 is in range 1-10: true
130             7 is in range 2-4,6,8-10: false
131             9 is in range 1,2,3-12: true
132 */
133 char is_in_range(int t, char*irange)
134 {
135     char*pos = irange;
136     char*digits;
137     int num;
138     char range = 0;
139     int last=0;
140     char tmp;
141
142     if(!irange)  // no range resembles (-OO,OO)
143         return 1;
144
145     while(*pos)
146     {
147         while(*pos == ' ' || *pos == '\r' || *pos == '\n' || *pos == '\t')
148             pos++;
149
150         digits = pos;
151         while(*digits>='0' && *digits<='9')
152             digits++;
153         if(digits == pos) {
154             fprintf(stderr, "Error: \"%s\" is not a valid format (digit expected)\n",irange);
155             exit(1);
156         }
157         
158         tmp=*digits;*digits=0;
159         num = atoi(pos);
160         *digits=tmp;
161         pos = digits;
162
163         while(*pos == ' ' || *pos == '\r' || *pos == '\n' || *pos == '\t')
164             pos++;
165
166         if(range && last<=t && num>=t)
167             return 1;
168         if(range) {
169             range = 0;
170             if(*pos)
171              pos ++;
172             continue;
173         }
174
175         if(*pos=='-')
176         {
177             if(range) {
178                 fprintf(stderr, "Error: \"%s\" is not a valid format (too many '-'s)\n",irange);
179                 exit(1);
180             }
181             last = num;
182             range = 1;
183             if(*pos)
184              pos ++;
185             continue;
186         } 
187         else 
188         {
189             /* if it isn't a '-', we assume it is a seperator like
190                ',', ';', ':', whatever. */
191             if(t == num)
192                 return 1;
193             if(*pos)
194              pos ++;
195             continue;
196         }
197     }
198     if(range && last<=t)
199         return 1;
200     return 0;
201 }
202
203 int main(int argn, char *argv[])
204 {
205     processargs(argn, argv);
206     initLog(0,-1,0,0,-1,loglevel);
207
208     // test if the page range is o.k.
209     is_in_range(0x7fffffff, pagerange);
210
211     if (!filename) {
212         args_callback_usage(argv[0]);
213         exit(0);
214     }
215
216     logf("<verbose> reading data files from %s\n", DATADIR);
217     //TODO: use tempnam here. Check if environment already contains a
218     //T1LIB_CONFIG.
219     putenv( "T1LIB_CONFIG=/tmp/t1lib.config.tmp");
220     FILE*fi = fopen("/tmp/t1lib.config.tmp", "wb");
221     fprintf(fi, "FONTDATABASE=%s/FontDataBase\n", DATADIR);
222     fprintf(fi, "ENCODING=%s:.\n", DATADIR);
223     fprintf(fi, "AFM=%s:.\n", DATADIR);
224     fprintf(fi, "TYPE1=%s:.\n", DATADIR);
225     fclose(fi);
226     /* initialize t1lib */
227     T1_SetBitmapPad( 16);
228     if ((T1_InitLib(NO_LOGFILE)==NULL)){
229         fprintf(stderr, "Initialization of t1lib failed\n");
230         exit(1);
231     }
232     unlink("/tmp/t1lib.config.tmp");
233
234     pdfswf_init(filename, password);
235     pdfswf_setoutputfilename(outputname);
236
237     int pages = pdfswf_numpages();
238     int t = 1;
239     for(t = 1; t <= pages; t++) 
240     {
241         if(is_in_range(t, pagerange))
242         pdfswf_convertpage(t);
243     }
244
245     pdfswf_close();
246     return 0;
247 }
248
249