1 /* autotrace.h --- Autotrace API
2 
3   Copyright (C) 2000, 2001, 2002 Martin Weber
4 
5   The author can be contacted at <martweb@gmx.net>
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 as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11 
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16 
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 
21 #ifndef AUTOTRACE_H
22 #define AUTOTRACE_H
23 
24 #include <stdio.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif /* __cplusplus */
29 
30 #ifndef N_
31 #define N_(x) x
32 #endif /* Not def: N_ */
33 
34 /* ===================================================================== *
35  * Typedefs
36  * ===================================================================== */
37 
38 #include "types.h"
39 
40 typedef struct _at_fitting_opts_type at_fitting_opts_type;
41 typedef struct _at_input_opts_type   at_input_opts_type;
42 typedef struct _at_output_opts_type  at_output_opts_type;
43 typedef struct _at_bitmap_type at_bitmap_type;
44 typedef struct _at_color_type at_color_type;
45 typedef enum _at_polynomial_degree at_polynomial_degree;
46 typedef struct _at_spline_type at_spline_type;
47 typedef struct _at_spline_list_type at_spline_list_type;
48 typedef struct _at_spline_list_array_type at_spline_list_array_type;
49 #define at_splines_type at_spline_list_array_type
50 typedef enum _at_msg_type at_msg_type;
51 
52 /* Color in RGB */
53 struct _at_color_type
54 {
55   unsigned char r;
56   unsigned char g;
57   unsigned char b;
58 };
59 
60 /* Third degree is the highest we deal with.  */
61 enum _at_polynomial_degree
62 {
63   AT_LINEARTYPE = 1,
64   AT_QUADRATICTYPE = 2,
65   AT_CUBICTYPE = 3,
66   AT_PARALLELELLIPSETYPE = 4,
67   AT_ELLIPSETYPE = 5,
68   AT_CIRCLETYPE = 6
69   /* not the real number of points to define a
70      circle but to distinguish between a cubic spline */
71 };
72 
73 /* A Bezier spline can be represented as four points in the real plane:
74    a starting point, ending point, and two control points.  The
75    curve always lies in the convex hull defined by the four points.  It
76    is also convenient to save the divergence of the spline from the
77    straight line defined by the endpoints.  */
78 struct _at_spline_type
79 {
80   at_real_coord v[4];	/* The control points.  */
81   at_polynomial_degree degree;
82   at_real linearity;
83 };
84 
85 /* Each outline in a character is typically represented by many
86    splines.  So, here is a list structure for that:  */
87 struct _at_spline_list_type
88 {
89   at_spline_type *data;
90   unsigned length;
91   at_bool clockwise;
92   at_color_type color;
93   at_bool open;
94 };
95 
96 /* Each character is in general made up of many outlines. So here is one
97    more list structure.  */
98 struct _at_spline_list_array_type
99 {
100   at_spline_list_type *data;
101   unsigned length;
102 
103   /* splines bbox */
104   unsigned short height, width;
105 
106   /* the values for following members are inherited from
107      at_fitting_opts_type */
108   at_color_type * background_color;
109   at_bool centerline;
110   at_bool preserve_width;
111   at_real width_weight_factor;
112 
113 };
114 
115 /* Fitting option.
116    With using at_fitting_opts_doc macro, the description of
117    each option could be get. e.g. at_fitting_opts_doc(background_color) */
118 struct _at_fitting_opts_type
119 {
120 #define at_doc__background_color					\
121 N_("background-color <hexadezimal>: the color of the background that "	\
122 "should be ignored, for example FFFFFF; "				\
123 "default is no background color.")
124   at_color_type *background_color;
125 
126 #define at_doc__color_count							\
127 N_("color-count <unsigned>: number of colors a color bitmap is reduced to, "	\
128 "it does not work on grayscale, allowed are 1..256; "				\
129 "default is 0, that means not color reduction is done.")
130   unsigned color_count;
131 
132 #define at_doc__corner_always_threshold						\
133 N_("corner-always-threshold <angle-in-degrees>: if the angle at a pixel is "	\
134 "less than this, it is considered a corner, even if it is within "		\
135 "`corner-surround' pixels of another corner; default is 60. ")
136   at_real corner_always_threshold;
137 
138 #define at_doc__corner_surround						\
139 N_("corner-surround <unsigned>: number of pixels on either side of a "	\
140 "point to consider when determining if that point is a corner; "	\
141 "default is 4. ")
142   unsigned corner_surround;
143 
144 #define  at_doc__corner_threshold						\
145 N_("corner-threshold <angle-in-degrees>: if a pixel, its predecessor(s), "	\
146 "and its successor(s) meet at an angle smaller than this, it's a "		\
147 "corner; default is 100. ")
148   at_real corner_threshold;
149 
150 #define at_doc__error_threshold						\
151 N_("error-threshold <real>: subdivide fitted curves that are off by "	\
152 "more pixels than this; default is 2.0. ")
153   at_real error_threshold;
154 
155 #define  at_doc__filter_iterations					\
156 N_("filter-iterations <unsigned>: smooth the curve this many times "	\
157 "before fitting; default is 4.")
158   unsigned filter_iterations;
159 
160 #define at_doc__line_reversion_threshold					\
161 N_("line-reversion-threshold <real>: if a spline is closer to a straight "	\
162 "line than this, weighted by the square of the curve length, keep it a "	\
163 "straight line even if it is a list with curves; default is .01. ")
164   at_real line_reversion_threshold;
165 
166 #define at_doc__line_threshold							\
167 N_("line-threshold <real>: if the spline is not more than this far away "	\
168 "from the straight line defined by its endpoints,"				\
169 "then output a straight line; default is 1. ")
170   at_real line_threshold;
171 
172 #define at_doc__remove_adjacent_corners					\
173 N_("remove-adjacent-corners: remove corners that are adjacent; "	\
174 "default doesn't remove.")
175   at_bool remove_adjacent_corners;
176 
177 #define at_doc__tangent_surround					\
178 N_("tangent-surround <unsigned>: number of points on either side of a "	\
179 "point to consider when computing the tangent at that point; "		\
180 " default is 3.")
181   unsigned tangent_surround;
182 
183 #define at_doc__despeckle_level						\
184 N_("despeckle-level <unsigned>: 0..20; default is no despeckling. ")
185   unsigned despeckle_level;
186 
187 #define at_doc__despeckle_tightness				\
188 N_("despeckle-tightness <real>: 0.0..8.0; default is 2.0. ")
189   at_real despeckle_tightness;
190 
191 #define  at_doc__centerline						\
192 N_("centerline: trace a character's centerline, rather than its outline. ")
193   at_bool centerline;
194 
195 #define at_doc__preserve_width							\
196 N_("preserve-width: whether to preserve linewith with centerline fitting; "	\
197 "default doesn't preserve.")
198   at_bool preserve_width;
199 
200 #define  at_doc__width_weight_factor				\
201 N_("width-weight-factor: weight factor for fitting the linewidth")
202   at_real width_weight_factor;
203 };
204 
205 struct _at_input_opts_type
206 {
207   at_color_type *background_color;
208 };
209 
210 struct _at_output_opts_type
211 {
212   int dpi;			/* DPI is used only in MIF output.*/
213 };
214 
215 struct _at_bitmap_type
216 {
217   unsigned short height;
218   unsigned short width;
219   unsigned char *bitmap;
220   unsigned int np;
221 };
222 
223 enum _at_msg_type
224 {
225   AT_MSG_FATAL = 1,
226   AT_MSG_WARNING,
227 };
228 
229 typedef
230 void (* at_msg_func) (at_string msg, at_msg_type msg_type, at_address client_data);
231 
232 /*
233  * IO Handler typedefs
234  */
235 
236 typedef
237 at_bitmap_type (*at_input_read_func)   (at_string name,
238 					at_input_opts_type * opts,
239 					at_msg_func msg_func,
240 					at_address msg_data);
241 
242 typedef
243 int            (*at_output_write_func) (FILE*, at_string name,
244 					int llx, int lly,
245 					int urx, int ury,
246 					at_output_opts_type * opts,
247 					at_splines_type shape,
248 					at_msg_func msg_func,
249 					at_address msg_data);
250 
251 /*
252  * Progress handler typedefs
253  * 0.0 <= percentage <= 1.0
254  */
255 typedef void           (* at_progress_func)    (at_real percentage,
256 						at_address client_data);
257 
258 /*
259  * Test cancel
260  * Return true if auto-tracing should be stopped.
261  */
262 typedef at_bool          (*  at_testcancel_func) (at_address client_data);
263 
264 /* ===================================================================== *
265  * Functions
266  * ===================================================================== */
267 
268 /* --------------------------------------------------------------------- *
269  * Fitting option related
270  *
271  * TODO: internal data access, copy
272  * --------------------------------------------------------------------- */
273 at_fitting_opts_type * at_fitting_opts_new(void);
274 at_fitting_opts_type * at_fitting_opts_copy (at_fitting_opts_type * original);
275 void at_fitting_opts_free(at_fitting_opts_type * opts);
276 
277 /* TODO: Gettextize */
278 #define at_fitting_opts_doc(opt) _(at_doc__##opt)
279 
280 /* --------------------------------------------------------------------- *
281  * Input option related
282  *
283  * TODO: internal data access
284  * --------------------------------------------------------------------- */
285 at_input_opts_type * at_input_opts_new(void);
286 at_input_opts_type * at_input_opts_copy(at_input_opts_type * original);
287 void at_input_opts_free(at_input_opts_type * opts);
288 
289 /* --------------------------------------------------------------------- *
290  * Output option related
291  *
292  * TODO: internal data access
293  * --------------------------------------------------------------------- */
294 at_output_opts_type * at_output_opts_new(void);
295 at_output_opts_type * at_output_opts_copy(at_output_opts_type * original);
296 void at_output_opts_free(at_output_opts_type * opts);
297 
298 /* --------------------------------------------------------------------- *
299  * Bitmap related
300  *
301  * TODO: internal data access
302  * --------------------------------------------------------------------- */
303 
304 /* There is two way to build at_bitmap_type.
305    1. Using input reader
306       Use at_bitmap_read.
307       at_input_get_handler_by_suffix or
308       at_input_get_handler will help you to get at_input_read_func.
309    2. Allocating a bitmap and rendering an image on it by yourself
310       Use at_bitmap_new.
311 
312    In both case, you have to call at_bitmap_free when at_bitmap_type *
313    data are no longer needed. */
314 at_bitmap_type * at_bitmap_read (at_input_read_func input_reader,
315 				 at_string filename,
316 				 at_input_opts_type * opts,
317 				 at_msg_func msg_func, at_address msg_data);
318 at_bitmap_type * at_bitmap_new(unsigned short width,
319 			       unsigned short height,
320 			       unsigned int planes);
321 at_bitmap_type * at_bitmap_copy(at_bitmap_type * src);
322 
323 /* We have to export functions that supports internal datum
324    access. Such functions might be useful for
325    at_bitmap_new user. */
326 unsigned short at_bitmap_get_width (at_bitmap_type * bitmap);
327 unsigned short at_bitmap_get_height (at_bitmap_type * bitmap);
328 unsigned short at_bitmap_get_planes (at_bitmap_type * bitmap);
329 void at_bitmap_free (at_bitmap_type * bitmap);
330 
331 
332 /* --------------------------------------------------------------------- *
333  * Spline related
334  *
335  * TODO: internal data access
336  * --------------------------------------------------------------------- */
337 /* at_splines_new
338 
339    args:
340 
341    BITMAP is modified in at_splines_new according to opts. Therefore
342    if you need the original bitmap image, you have to make a backup of
343    BITMAP with using at_bitmap_copy.
344 
345    MSG_FUNC and MSG_DATA are used to notify a client errors and
346    warning from autotrace. NULL is valid value for MSG_FUNC if
347    the client is not interested in the notifications. */
348 at_splines_type * at_splines_new (at_bitmap_type * bitmap,
349 				  at_fitting_opts_type * opts,
350 				  at_msg_func msg_func, at_address msg_data);
351 
352 /* at_splines_new_full
353 
354    args:
355 
356    NOTIFY_PROGRESS is called repeatedly inside at_splines_new_full
357    to notify the progress of the execution. This might be useful for
358    interactive applications. NOTIFY_PROGRESS is called following
359    format:
360 
361    NOTIFY_PROGRESS (percentage, progress_data);
362 
363    test_cancel is called repeatedly inside at_splines_new_full
364    to test whether the execution is canceled or not.
365    If test_cancel returns TRUE, execution of at_splines_new_full
366    is stopped as soon as possible and returns NULL. If test_cancel
367    returns FALSE, nothing happens. test_cancel  is called following
368    format:
369 
370    TEST_CANCEL (testcancel_data);
371 
372    NULL is valid value for notify_progress and/or test_cancel if
373    you don't need to know the progress of the execution and/or
374    cancel the execution */
375 at_splines_type * at_splines_new_full (at_bitmap_type * bitmap,
376 				       at_fitting_opts_type * opts,
377 				       at_msg_func msg_func,
378 				       at_address msg_data,
379 				       at_progress_func notify_progress,
380 				       at_address progress_data,
381 				       at_testcancel_func test_cancel,
382 				       at_address testcancel_data);
383 
384 void at_splines_write(at_output_write_func output_writer,
385 		  FILE * writeto,
386 		  at_string file_name,
387 		  at_output_opts_type * opts,
388 		  at_splines_type * splines,
389 		  at_msg_func msg_func, at_address msg_data);
390 
391 void at_splines_free (at_splines_type * splines);
392 
393 /* --------------------------------------------------------------------- *
394  * Color related
395  * --------------------------------------------------------------------- */
396 at_color_type * at_color_new   (unsigned char r,
397 				unsigned char g,
398 			        unsigned char b);
399 at_color_type * at_color_copy  (at_color_type * original);
400 at_bool         at_color_equal (at_color_type * c1, at_color_type * c2);
401 void            at_color_free  (at_color_type * color);
402 
403 /* --------------------------------------------------------------------- *
404  * Input related
405  * --------------------------------------------------------------------- */
406 at_input_read_func at_input_get_handler (at_string filename);
407 at_input_read_func at_input_get_handler_by_suffix (at_string suffix);
408 
409 char ** at_input_list_new (void);
410 void at_input_list_free(char ** list);
411 
412 /* at_input_shortlist
413    return value: Do free by yourself */
414 char * at_input_shortlist (void);
415 
416 /* --------------------------------------------------------------------- *
417  * Output related
418  * --------------------------------------------------------------------- */
419 at_output_write_func at_output_get_handler (at_string filename);
420 at_output_write_func at_output_get_handler_by_suffix (at_string suffix);
421 char ** at_output_list_new (void);
422 void at_output_list_free(char ** list);
423 
424 /* at_output_shortlist
425    return value: Do free by yourself */
426 char * at_output_shortlist (void);
427 
428 /* --------------------------------------------------------------------- *
429  * Misc
430  * --------------------------------------------------------------------- */
431 
432 /* at_version
433 
434    args:
435    LONG_FORMAT == true: "AutoTrace version x.y"
436    LONG_FORMAT == false: "x.y"
437 
438    return value: Don't free. It is allocated statically */
439 const char * at_version (at_bool long_format);
440 
441 /* at_home_site
442 
443    return value: Don't free. It is allocated statically */
444 const char * at_home_site (void);
445 
446 #ifdef __cplusplus
447 }
448 #endif /* __cplusplus */
449 
450 #endif /* AUTOTRACE_H */
451