int output_fig_writer(FILE * file, gchar * name, int llx, int lly, int urx, int ury, at_output_opts_type * opts, spline_list_array_type shape, at_msg_func msg_func, gpointer msg_data, gpointer user_data) { at_exception_type exp = at_exception_new(msg_func, msg_data); /* Output header */ fprintf(file, "#FIG 3.2\nLandscape\nCenter\nInches\nLetter\n100.00\nSingle\n-2\n1200 2\n"); /* Output data */ out_fig_splines(file, shape, llx, lly, urx, ury, &exp); return 0; }
at_bitmap input_gf_reader (gchar* filename, at_input_opts_type *opts, at_msg_func msg_func, gpointer msg_data, gpointer user_data) { at_exception_type exp = at_exception_new (msg_func, msg_data); at_bitmap bitmap = at_bitmap_init (NULL, 0, 0, 0); gf_font_t fontdata, *font = &fontdata; gf_char_t chardata, *sym = &chardata; unsigned int i, j, ptr; if (! gf_open (font, filename)) { at_exception_fatal (&exp, "Cannot open input GF file"); return bitmap; } if (opts->charcode == 0) { /* Find a first character in font file. */ for (i=0; i<256; ++i) if (font->char_loc[i].char_pointer != -1) break; if (i >= 256) { at_exception_fatal (&exp, "No characters in input GF file"); return bitmap; } opts->charcode = i; } if (! gf_get_char (font, sym, (unsigned char) opts->charcode)) { fclose (font->input_file); at_exception_fatal (&exp, "Error reading character from GF file"); return bitmap; } ugs_design_pixels = font->design_size * font->v_pixels_per_point + 0.5; ugs_charcode = opts->charcode; ugs_advance_width = sym->h_escapement; ugs_left_bearing = sym->bbox_min_col; ugs_descend = sym->bbox_min_row; ugs_max_col = sym->bbox_max_col; ugs_max_row = sym->bbox_max_row; bitmap = at_bitmap_init (NULL, sym->width, sym->height, 1); for (j=0, ptr=0; j<sym->height; j++) { for (i=0; i<sym->width; i++) { AT_BITMAP_BITS (&bitmap) [ptr++] = PIXEL (sym, j, i); } } if (sym->bitmap) free (sym->bitmap); fclose (font->input_file); return bitmap; }
at_bitmap input_png_reader(gchar* filename, at_input_opts_type * opts, at_msg_func msg_func, gpointer msg_data, gpointer user_data) { FILE *stream; at_bitmap image = at_bitmap_init(0, 0, 0, 1); at_exception_type exp = at_exception_new(msg_func, msg_data); stream = fopen(filename, "rb"); if (!stream) { LOG1("Can't open \"%s\"\n", filename); at_exception_fatal(&exp, "Cannot open input png file"); return image; } load_image(&image, stream, opts, &exp); fclose(stream); return image; }
/* at_splines_new_full modifies its 'bitmap' argument when it does the thin_image thing. */ at_spline_list_array_type * at_splines_new_full(at_bitmap_type * const bitmap, at_fitting_opts_type * const opts, at_msg_func msg_func, void * const msg_data, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, void * const testcancel_data) { at_spline_list_array_type * retval; image_header_type image_header; pixel_outline_list_type pixelOutlineList; at_exception_type exp; distance_map_type distanceMap; bool haveDistMap; exp = at_exception_new(msg_func, msg_data); image_header.width = at_bitmap_get_width(bitmap); image_header.height = at_bitmap_get_height(bitmap); if (opts->centerline) { if (opts->preserve_width) { /* Preserve line width prior to thinning. */ bool const paddedTrue = true; distanceMap = new_distance_map(*bitmap, 255, paddedTrue, &exp); haveDistMap = true; } else haveDistMap = false; thin_image(bitmap, opts->backgroundSpec, opts->background_color, &exp); } else haveDistMap = false; if (at_exception_got_fatal(&exp)) retval = NULL; else { if (opts->centerline) { pixel background_color; if (opts->backgroundSpec) background_color = opts->background_color; else PPM_ASSIGN(background_color, 255, 255, 255); pixelOutlineList = find_centerline_pixels(*bitmap, background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); } else pixelOutlineList = find_outline_pixels(*bitmap, opts->backgroundSpec, opts->background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); if (at_exception_got_fatal(&exp) || (test_cancel && test_cancel(testcancel_data))) retval = NULL; else { at_spline_list_array_type * splinesP; MALLOCVAR_NOFAIL(splinesP); fit_outlines_to_splines(pixelOutlineList, opts, haveDistMap ? &distanceMap : NULL, image_header.width, image_header.height, &exp, notify_progress, progress_data, test_cancel, testcancel_data, splinesP); if (at_exception_got_fatal(&exp) || (test_cancel && test_cancel(testcancel_data))) retval = NULL; else { if (notify_progress) notify_progress(1.0, progress_data); retval = splinesP; } free_pixel_outline_list(&pixelOutlineList); } if (haveDistMap) free_distance_map(&distanceMap); } return retval; }
/* at_splines_new_full modify its argument: BITMAP when despeckle, quantize and/or thin_image are invoked. */ at_splines_type * at_splines_new_full (at_bitmap * bitmap, at_fitting_opts_type * opts, at_msg_func msg_func, gpointer msg_data, at_progress_func notify_progress, gpointer progress_data, at_testcancel_func test_cancel, gpointer testcancel_data) { image_header_type image_header; at_splines_type * splines = NULL; pixel_outline_list_type pixels; QuantizeObj *myQuant = NULL; /* curently not used */ at_exception_type exp = at_exception_new(msg_func, msg_data); at_distance_map dist_map, *dist = NULL; #define CANCELP (test_cancel && test_cancel(testcancel_data)) #define FATALP (at_exception_got_fatal(&exp)) #define FREE_SPLINE() do {if (splines) {at_splines_free(splines); splines = NULL;}} while(0) #define CANCEL_THEN_CLEANUP_DIST() if (CANCELP) goto cleanup_dist; #define CANCEL_THEN_CLEANUP_PIXELS() if (CANCELP) {FREE_SPLINE(); goto cleanup_pixels;} #define FATAL_THEN_RETURN() if (FATALP) return splines; #define FATAL_THEN_CLEANUP_DIST() if (FATALP) goto cleanup_dist; #define FATAL_THEN_CLEANUP_PIXELS() if (FATALP) {FREE_SPLINE(); goto cleanup_pixels;} if (opts->despeckle_level > 0) { despeckle (bitmap, opts->despeckle_level, opts->despeckle_tightness, opts->noise_removal, &exp); FATAL_THEN_RETURN(); } image_header.width = at_bitmap_get_width(bitmap); image_header.height = at_bitmap_get_height(bitmap); if (opts->color_count > 0) { quantize (bitmap, opts->color_count, opts->background_color, &myQuant, &exp); if (myQuant) quantize_object_free(myQuant); /* curently not used */ FATAL_THEN_RETURN(); } if (opts->centerline) { if (opts->preserve_width) { /* Preserve line width prior to thinning. */ dist_map = new_distance_map(bitmap, 255, /*padded=*/TRUE, &exp); dist = &dist_map; FATAL_THEN_RETURN(); } /* Hereafter, dist is allocated. dist must be freed if the execution is canceled or exception is raised; use FATAL_THEN_CLEANUP_DIST. */ thin_image (bitmap, opts->background_color, &exp); FATAL_THEN_CLEANUP_DIST() } /* Hereafter, pixels is allocated. pixels must be freed if the execution is canceled; use CANCEL_THEN_CLEANUP_PIXELS. */ if (opts->centerline) { at_color background_color = { 0xff, 0xff, 0xff }; if (opts->background_color) background_color = *opts->background_color; pixels = find_centerline_pixels(bitmap, background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); } else pixels = find_outline_pixels(bitmap, opts->background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); FATAL_THEN_CLEANUP_DIST(); CANCEL_THEN_CLEANUP_DIST(); XMALLOC(splines, sizeof(at_splines_type)); *splines = fitted_splines (pixels, opts, dist, image_header.width, image_header.height, &exp, notify_progress, progress_data, test_cancel, testcancel_data); FATAL_THEN_CLEANUP_PIXELS(); CANCEL_THEN_CLEANUP_PIXELS(); if (notify_progress) notify_progress(1.0, progress_data); cleanup_pixels: free_pixel_outline_list (&pixels); cleanup_dist: if (dist) free_distance_map (dist); return splines; #undef CANCELP #undef FATALP #undef FREE_SPLINE #undef CANCEL_THEN_CLEANUP_DIST #undef CANCEL_THEN_CLEANUP_PIXELS #undef FATAL_THEN_RETURN #undef FATAL_THEN_CLEANUP_DIST #undef FATAL_THEN_CLEANUP_PIXELS }