1 /*
2  * tumble: build a PDF file from image files
3  *
4  * Input handler dispatch
5  * Copyright 2001, 2002, 2003, 2017 Eric Smith <spacewar@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.  Note that permission is
10  * not granted to redistribute this program under the terms of any
11  * other version of the General Public License.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21  *
22  *  2007-05-07 [JDB] Add support for blank pages and fix a bug that caused a
23  *                   double free.
24  */
25 
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 
34 #include "semantics.h"
35 #include "tumble.h"
36 #include "bitblt.h"
37 #include "pdf.h"
38 #include "tumble_input.h"
39 
40 
41 #define MAX_INPUT_HANDLERS 10
42 
43 static int input_handler_count = 0;
44 
45 static input_handler_t *input_handlers [MAX_INPUT_HANDLERS];
46 
47 
48 static char *in_filename;
49 static FILE *in;
50 static input_handler_t *current_input_handler;
51 
52 
install_input_handler(input_handler_t * handler)53 void install_input_handler (input_handler_t *handler)
54 {
55   if (input_handler_count >= MAX_INPUT_HANDLERS)
56     fprintf (stderr, "Too many input handlers, table only has room for %d\n", MAX_INPUT_HANDLERS);
57   else
58     input_handlers [input_handler_count++] = handler;
59 }
60 
61 
match_input_suffix(char * suffix)62 bool match_input_suffix (char *suffix)
63 {
64   int i;
65   for (i = 0; i < input_handler_count; i++)
66     if (input_handlers [i]->match_suffix (suffix))
67       return (1);
68   return (0);
69 }
70 
71 
open_input_file(char * name)72 bool open_input_file (char *name)
73 {
74   int i;
75 
76   if (name == NULL)
77     {
78       if (in)
79 	close_input_file ();
80       current_input_handler = & blank_handler;
81       return (1);
82     }
83 
84   if (in)
85     {
86       if (strcmp (name, in_filename) == 0)
87 	return (1);
88       close_input_file ();
89     }
90   in_filename = strdup (name);
91   if (! in_filename)
92     {
93       fprintf (stderr, "can't strdup input filename '%s'\n", name);
94       goto fail;
95     }
96 
97   in = fopen (name, "rb");
98   if (! in)
99     goto fail;
100 
101   for (i = 0; i < input_handler_count; i++)
102     {
103       if (input_handlers [i]->open_input_file (in, name))
104 	break;
105     }
106   if (i >= input_handler_count)
107     {
108       fprintf (stderr, "unrecognized format for input file '%s'\n", name);
109       goto fail;
110     }
111   current_input_handler = input_handlers [i];
112   return (1);
113 
114  fail:
115   if (in)
116     fclose (in);
117   in = NULL;
118   return (0);
119 }
120 
121 
close_input_file(void)122 bool close_input_file (void)
123 {
124   bool result = 1;
125 
126   if (current_input_handler)
127     {
128       result = current_input_handler->close_input_file ();
129       current_input_handler = NULL;
130     }
131   if (in_filename) {
132     free (in_filename);
133     in_filename = NULL;
134   }
135   if (in)
136     {
137       fclose (in);
138       in = NULL;
139     }
140 
141   return (result);
142 }
143 
144 
last_input_page(void)145 bool last_input_page (void)
146 {
147   if (! current_input_handler)
148     return (0);
149   return (current_input_handler->last_input_page ());
150 }
151 
152 
get_image_info(int image,input_attributes_t input_attributes,image_info_t * image_info)153 bool get_image_info (int image,
154 		     input_attributes_t input_attributes,
155 		     image_info_t *image_info)
156 {
157   if (! current_input_handler)
158     return (0);
159   return (current_input_handler->get_image_info (image,
160 						 input_attributes,
161 						 image_info));
162 }
163 
process_image(int image,input_attributes_t input_attributes,image_info_t * image_info,pdf_page_handle page,position_t position)164 bool process_image (int image,
165 		    input_attributes_t input_attributes,
166 		    image_info_t *image_info,
167 		    pdf_page_handle page,
168 		    position_t position)
169 {
170   if (! current_input_handler)
171     return (0);
172   return (current_input_handler->process_image (image,
173 						input_attributes,
174 						image_info,
175 						page,
176 						position));
177 }
178