Commit f3b5ed43 authored by jean-pierre charras's avatar jean-pierre charras

Added an *experimental* tool (bitmap2component) to create logos from .bmp...

Added an *experimental* tool (bitmap2component) to create logos from .bmp bitmaps. Added Potrace library to convert bitmaps to polygons
    This tool uses potarce library that converts a bitmap picture (.bmp or .pgm format) to a set of polygons.
    bitmap2component converts a bitmap to a .emp footprint (that can be imported by modedit) or a .lib component that can be    imported by libedit.
    See changelog for more info
parents 82aadca8 076832cd
......@@ -4,6 +4,24 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with
email address.
2010-jun-10, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
Added an experimental tool (bitmap2component) to create logos from .bmp bitmaps. Added Potrace library to convert bitmaps to polygons
This tool uses potarce library that converts a bitmap picture (.bmp or .pgm format) to a set of polygons.
bitmap2component converts a bitmap to a .emp footprint (that can be imported by modedit) or a .lib component that can be
imported by libedit.
Note: imported bitmaps logos are vectored by potrace, so there is no pixelation effect.
Scale is 1:1 for 300ppi pictures.
bitmap2component currently runs only is command line mode
run
bitmap2component bitmapfile.bmp bitmapfile.lib 1 to create a schematic component logo
(import this file using libedit)
or
bitmap2component bitmapfile.bmp bitmapfile.emp 1 to create a footprint logo
(import this file using modedit)
2010-may-18, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++All:
......
......@@ -187,6 +187,8 @@ add_subdirectory(kicad)
add_subdirectory(pcbnew)
add_subdirectory(polygon)
add_subdirectory(polygon/kbool/src)
add_subdirectory(potrace)
add_subdirectory(bitmap2component)
#############
# Resources #
......
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
../potrace
../polygon/kbool/include
)
set(BITMAP2COMPONENT_SRCS
bitmap2component.cpp
)
add_executable(bitmap2component WIN32 MACOSX_BUNDLE ${BITMAP2COMPONENT_SRCS} ${BITMAP2COMPONENT_RESOURCES})
target_link_libraries( bitmap2component potrace kbool )
if(APPLE)
set_target_properties(bitmap2component PROPERTIES )
endif(APPLE)
install(TARGETS bitmap2component
DESTINATION ${KICAD_BIN}
COMPONENT binary)
This diff is collapsed.
......@@ -676,7 +676,7 @@ bool LIB_COMPONENT::Load( FILE* aFile, char* aLine, int* aLineNum,
{
aErrorMsg.Printf( wxT( "Wrong DEF format in line %d, skipped." ),
*aLineNum );
while( GetLine( aFile, aLine, aLineNum, 1024 ) )
while( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
{
p = strtok( aLine, " \t\n" );
if( stricmp( p, "ENDDEF" ) == 0 )
......@@ -726,7 +726,7 @@ bool LIB_COMPONENT::Load( FILE* aFile, char* aLine, int* aLineNum,
m_options = ENTRY_POWER;
/* Read next lines */
while( GetLine( aFile, aLine, aLineNum, 1024 ) )
while( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) )
{
p = strtok( aLine, " \t\n" );
......@@ -775,7 +775,7 @@ bool LIB_COMPONENT::LoadDrawEntries( FILE* aFile, char* aLine,
while( true )
{
if( GetLine( aFile, aLine, aLineNum, 1024 ) == NULL )
if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
{
aErrorMsg = wxT( "file ended prematurely loading component draw element" );
return false;
......@@ -830,7 +830,7 @@ bool LIB_COMPONENT::LoadDrawEntries( FILE* aFile, char* aLine,
/* Flush till end of draw section */
do
{
if( GetLine( aFile, aLine, aLineNum, 1024 ) == NULL )
if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
{
aErrorMsg = wxT( "file ended prematurely while attempting \
to flush to end of drawing section." );
......@@ -899,7 +899,7 @@ bool LIB_COMPONENT::LoadFootprints( FILE* aFile, char* aLine,
{
while( true )
{
if( GetLine( aFile, aLine, aLineNum, 1024 ) == NULL )
if( GetLine( aFile, aLine, aLineNum, LINE_BUFFER_LEN_LARGE ) == NULL )
{
aErrorMsg = wxT( "file ended prematurely while loading footprints" );
return false;
......
......@@ -551,7 +551,7 @@ bool CMP_LIBRARY::Load( wxString& aErrorMsg )
{
FILE* file;
int lineNumber = 0;
char line[1024];
char line[LINE_BUFFER_LEN_LARGE]; // Use a very large buffer to load data
LIB_COMPONENT* libEntry;
wxString msg;
......@@ -716,7 +716,7 @@ void CMP_LIBRARY::LoadAliases( LIB_COMPONENT* component )
bool CMP_LIBRARY::LoadHeader( FILE* libfile, int* LineNum )
{
char Line[1024], * text, * data;
char Line[LINE_BUFFER_LEN], * text, * data;
while( GetLine( libfile, Line, LineNum, sizeof(Line) ) )
{
......@@ -735,7 +735,7 @@ bool CMP_LIBRARY::LoadHeader( FILE* libfile, int* LineNum )
bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg )
{
int lineNumber = 0;
char line[1024], * name, * text;
char line[LINE_BUFFER_LEN_LARGE], * name, * text;
CMP_LIB_ENTRY* entry;
FILE* file;
wxString msg;
......
......@@ -1369,6 +1369,8 @@ bool LIB_POLYLINE::Load( char* aLine, wxString& aErrorMsg )
i = sscanf( &aLine[2], "%d %d %d %d", &ccount, &m_Unit, &m_Convert,
&m_Width );
m_Fill = NO_FILL;
if( i < 4 )
{
aErrorMsg.Printf( _( "polyline only had %d parameters of the required 4" ), i );
......@@ -1389,13 +1391,13 @@ bool LIB_POLYLINE::Load( char* aLine, wxString& aErrorMsg )
{
wxPoint point;
p = strtok( NULL, " \t\n" );
if( sscanf( p, "%d", &pt.x ) != 1 )
if( p == NULL || sscanf( p, "%d", &pt.x ) != 1 )
{
aErrorMsg.Printf( _( "polyline point %d X position not defined" ), i );
return false;
}
p = strtok( NULL, " \t\n" );
if( sscanf( p, "%d", &pt.y ) != 1 )
if( p == NULL || sscanf( p, "%d", &pt.y ) != 1 )
{
aErrorMsg.Printf( _( "polyline point %d Y position not defined" ), i );
return false;
......@@ -1403,8 +1405,6 @@ bool LIB_POLYLINE::Load( char* aLine, wxString& aErrorMsg )
AddPoint( pt );
}
m_Fill = NO_FILL;
if( ( p = strtok( NULL, " \t\n" ) ) != NULL )
{
if( p[0] == 'F' )
......
......@@ -12,6 +12,10 @@
#define EESCHEMA_FILE_STAMP "EESchema"
#define NULL_STRING "_NONAME_"
// Define the char buffer size used to read library files
#define LINE_BUFFER_LEN_LARGE 8000
#define LINE_BUFFER_LEN 1024
#define MAX_PIN_INFO 10
#define TXTMARGE 10 /* Offset in mils for placement of labels
......
*
%FSLAX26Y26*%
%MOIN*%
G04 A4 - i274x.oc8.d36 *
%AMA4top*
4,1,8,
0.034500,0.014290,
0.034500,-0.014290,
0.014290,-0.034500,
-0.014290,-0.034500,
-0.034500,-0.014290,
-0.034500,0.014290,
-0.014290,0.034500,
0.014290,0.034500,
0.034500,0.014290,
0.0000*
%
%ADD40A4top*%
%IPPOS*%
%LNfp0149448top.gbx*%
%LPD*%
G75*
G54D40*
X04750000Y00344900D03*
X04856300Y00246400D03*
X04750000Y00148000D03*
M02*
......@@ -487,7 +487,7 @@ void Plot_1_EdgeModule( PLOTTER* plotter, EDGE_MODULE* PtEdge,
*ptr++ = y;
}
plotter->poly( PtEdge->m_PolyPoints.size(), ptr_base, NO_FILL,
plotter->poly( PtEdge->m_PolyPoints.size(), ptr_base, FILLED_SHAPE,
thickness );
free( ptr_base );
}
......
Known contributors are listed here, in alphabetical order by their
abbreviations (which are used in Changelog).
PS1 Peter Selinger <selinger at users.sourceforge.net> (author)
TA1 Tor Andersson <tor at ghostscript.com>
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
)
set(POTRACE_SRCS
bitmap_io.cpp
curve.cpp
decompose.cpp
greymap.cpp
potracelib.cpp
render.cpp
trace.cpp
)
add_library(potrace ${POTRACE_SRCS})
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* This header file collects some general-purpose macros (and static
* inline functions) that are used in various places. */
#ifndef AUXILIARY_H
#define AUXILIARY_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* ---------------------------------------------------------------------- */
/* point arithmetic */
#include "potracelib.h"
struct point_s
{
long x;
long y;
};
typedef struct point_s point_t;
typedef potrace_dpoint_t dpoint_t;
/* convert point_t to dpoint_t */
static inline dpoint_t dpoint( point_t p )
{
dpoint_t res;
res.x = p.x;
res.y = p.y;
return res;
}
/* range over the straight line segment [a,b] when lambda ranges over [0,1] */
static inline dpoint_t interval( double lambda, dpoint_t a, dpoint_t b )
{
dpoint_t res;
res.x = a.x + lambda * (b.x - a.x);
res.y = a.y + lambda * (b.y - a.y);
return res;
}
/* ---------------------------------------------------------------------- */
/* some useful macros. Note: the "mod" macro works correctly for
* negative a. Also note that the test for a>=n, while redundant,
* speeds up the mod function by 70% in the average case (significant
* since the program spends about 16% of its time here - or 40%
* without the test). The "floordiv" macro returns the largest integer
* <= a/n, and again this works correctly for negative a, as long as
* a,n are integers and n>0. */
/* integer arithmetic */
static inline int mod( int a, int n )
{
return a>=n ? a % n : a>=0 ? a : n - 1 - (-1 - a) % n;
}
static inline int floordiv( int a, int n )
{
return a>=0 ? a / n : -1 - (-1 - a) / n;
}
/* Note: the following work for integers and other numeric types. */
#undef sign
#undef abs
#undef min
#undef max
#undef sq
#undef cu
#define sign( x ) ( (x)>0 ? 1 : (x)<0 ? -1 : 0 )
#define abs( a ) ( (a)>0 ? (a) : -(a) )
#define min( a, b ) ( (a)<(b) ? (a) : (b) )
#define max( a, b ) ( (a)>(b) ? (a) : (b) )
#define sq( a ) ( (a) * (a) )
#define cu( a ) ( (a) * (a) * (a) )
#endif /* AUXILIARY_H */
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
#ifndef BITMAP_H
#define BITMAP_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
/* The bitmap type is defined in potracelib.h */
#include "potracelib.h"
/* The present file defines some convenient macros and static inline
* functions for accessing bitmaps. Since they only produce inline
* code, they can be conveniently shared by the library and frontends,
* if desired */
/* ---------------------------------------------------------------------- */
/* some measurements */
#define BM_WORDSIZE ( (int) sizeof(potrace_word) )
#define BM_WORDBITS (8 * BM_WORDSIZE)
#define BM_HIBIT ( ( (potrace_word) 1 ) << (BM_WORDBITS - 1) )
#define BM_ALLBITS (~(potrace_word) 0)
/* macros for accessing pixel at index (x,y). U* macros omit the
* bounds check. */
#define bm_scanline( bm, y ) ( (bm)->map + (y) * (bm)->dy )
#define bm_index( bm, x, y ) (&bm_scanline( bm, y )[(x) / BM_WORDBITS])
#define bm_mask( x ) ( BM_HIBIT >> ( (x) & (BM_WORDBITS - 1) ) )
#define bm_range( x, a ) ( (int) (x) >= 0 && (int) (x) < (a) )
#define bm_safe( bm, x, y ) ( bm_range( x, (bm)->w ) && bm_range( y, (bm)->h ) )
#define BM_UGET( bm, x, y ) ( ( *bm_index( bm, x, y ) & bm_mask( x ) ) != 0 )
#define BM_USET( bm, x, y ) ( *bm_index( bm, x, y ) |= bm_mask( x ) )
#define BM_UCLR( bm, x, y ) ( *bm_index( bm, x, y ) &= ~bm_mask( x ) )
#define BM_UINV( bm, x, y ) ( *bm_index( bm, x, y ) ^= bm_mask( x ) )
#define BM_UPUT( bm, x, y, b ) ( (b) ? BM_USET( bm, x, y ) : BM_UCLR( bm, x, y ) )
#define BM_GET( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UGET( bm, x, y ) : 0)
#define BM_SET( bm, x, y ) (bm_safe( bm, x, y ) ? BM_USET( bm, x, y ) : 0)
#define BM_CLR( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UCLR( bm, x, y ) : 0)
#define BM_INV( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UINV( bm, x, y ) : 0)
#define BM_PUT( bm, x, y, b ) (bm_safe( bm, x, y ) ? BM_UPUT( bm, x, y, b ) : 0)
/* free the given bitmap. Leaves errno untouched. */
static inline void bm_free( potrace_bitmap_t* bm )
{
if( bm )
{
free( bm->map );
}
free( bm );
}
/* return new un-initialized bitmap. NULL with errno on error */
static inline potrace_bitmap_t* bm_new( int w, int h )
{
potrace_bitmap_t* bm;
int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS;
bm = (potrace_bitmap_t*) malloc( sizeof(potrace_bitmap_t) );
if( !bm )
{
return NULL;
}
bm->w = w;
bm->h = h;
bm->dy = dy;
bm->map = (potrace_word*) malloc( dy * h * BM_WORDSIZE );
if( !bm->map )
{
free( bm );
return NULL;
}
return bm;
}
/* clear the given bitmap. Set all bits to c. */
static inline void bm_clear( potrace_bitmap_t* bm, int c )
{
memset( bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE );
}
/* duplicate the given bitmap. Return NULL on error with errno set. */
static inline potrace_bitmap_t* bm_dup( const potrace_bitmap_t* bm )
{
potrace_bitmap_t* bm1 = bm_new( bm->w, bm->h );
if( !bm1 )
{
return NULL;
}
memcpy( bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE );
return bm1;
}
/* invert the given bitmap. */
static inline void bm_invert( potrace_bitmap_t* bm )
{
int i;
for( i = 0; i < bm->dy * bm->h; i++ )
{
bm->map[i] ^= BM_ALLBITS;
}
}
#endif /* BITMAP_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* $Id: bitmap_io.h 147 2007-04-09 00:44:09Z selinger $ */
/* bitmap input/output functions */
#ifndef BITMAP_IO_H
#define BITMAP_IO_H
#include <stdio.h>
#include "bitmap.h"
/* Note that bitmaps are stored bottom to top, i.e., the first
* scanline is the bottom-most one */
extern char* bm_read_error;
int bm_read( FILE* f, double blacklevel, potrace_bitmap_t** bmp );
void bm_writepbm( FILE* f, potrace_bitmap_t* bm );
int bm_print( FILE* f, potrace_bitmap_t* bm );
#endif /* BITMAP_IO_H */
/* Copyright (C) 2001-2007 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
/* $Id: bitops.h 147 2007-04-09 00:44:09Z selinger $ */
/* bits.h: this file defines some macros for bit manipulations. We
provide a generic implementation */
/* lobit: return the position of the rightmost "1" bit of an int, or
32 if none. hibit: return 1 + the position of the leftmost "1" bit
of an int, or 0 if none. Note: these functions work on 32-bit
integers. */
#ifndef BITOPS_H
#define BITOPS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* generic macros */
static inline unsigned int lobit(unsigned int x) {
unsigned int res = 32;
while (x & 0xffffff) {
x <<= 8;
res -= 8;
}
while (x) {
x <<= 1;
res -= 1;
}
return res;
}
static inline unsigned int hibit(unsigned int x) {
unsigned int res = 0;
while (x > 0xff) {
x >>= 8;
res += 8;
}
while (x) {
x >>= 1;
res += 1;
}
return res;
}
#endif /* BITOPS_H */
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* $Id: curve.c 147 2007-04-09 00:44:09Z selinger $ */
/* private part of the path and curve data structures */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "potracelib.h"
#include "lists.h"
#include "curve.h"
#define SAFE_MALLOC( var, n, typ ) \
if( ( var = (typ*) malloc( (n)* sizeof(typ) ) ) == NULL ) \
goto malloc_error
/* ---------------------------------------------------------------------- */
/* allocate and free path objects */
path_t* path_new( void )
{
path_t* p = NULL;
privpath_t* priv = NULL;
SAFE_MALLOC( p, 1, path_t );
memset( p, 0, sizeof(path_t) );
SAFE_MALLOC( priv, 1, privpath_t );
memset( priv, 0, sizeof(privpath_t) );
p->priv = priv;
return p;
malloc_error:
free( p );
free( priv );
return NULL;
}
/* free the members of the given curve structure. Leave errno unchanged. */
static void privcurve_free_members( privcurve_t* curve )
{
free( curve->tag );
free( curve->c );
free( curve->vertex );
free( curve->alpha );
free( curve->alpha0 );
free( curve->beta );
}
/* free a path. Leave errno untouched. */
void path_free( path_t* p )
{
if( p )
{
if( p->priv )
{
free( p->priv->pt );
free( p->priv->lon );
free( p->priv->sums );
free( p->priv->po );
privcurve_free_members( &p->priv->curve );
privcurve_free_members( &p->priv->ocurve );
}
free( p->priv );
/* do not free p->fcurve ! */
}
free( p );
}
/* free a pathlist, leaving errno untouched. */
void pathlist_free( path_t* plist )
{
path_t* p;
list_forall_unlink( p, plist ) {
path_free( p );
}
}
/* ---------------------------------------------------------------------- */
/* initialize and finalize curve structures */
typedef dpoint_t dpoint3_t[3];
/* initialize the members of the given curve structure to size m.
* Return 0 on success, 1 on error with errno set. */
int privcurve_init( privcurve_t* curve, int n )
{
memset( curve, 0, sizeof(privcurve_t) );
curve->n = n;
SAFE_MALLOC( curve->tag, n, int );
SAFE_MALLOC( curve->c, n, dpoint3_t );
SAFE_MALLOC( curve->vertex, n, dpoint_t );
SAFE_MALLOC( curve->alpha, n, double );
SAFE_MALLOC( curve->alpha0, n, double );
SAFE_MALLOC( curve->beta, n, double );
return 0;
malloc_error:
free( curve->tag );
free( curve->c );
free( curve->vertex );
free( curve->alpha );
free( curve->alpha0 );
free( curve->beta );
return 1;
}
/* copy private to public curve structure */
void privcurve_to_curve( privcurve_t* pc, potrace_curve_t* c )
{
c->n = pc->n;
c->tag = pc->tag;
c->c = pc->c;
}
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
#ifndef CURVE_H
#define CURVE_H
#include "auxiliary.h"
/* vertex is c[1] for tag=POTRACE_CORNER, and the intersection of
* .c[-1][2]..c[0] and c[1]..c[2] for tag=POTRACE_CURVETO. alpha is only
* defined for tag=POTRACE_CURVETO and is the alpha parameter of the curve:
* .c[-1][2]..c[0] = alpha*(.c[-1][2]..vertex), and
* c[2]..c[1] = alpha*(c[2]..vertex).
* Beta is so that (.beta[i])[.vertex[i],.vertex[i+1]] = .c[i][2].
*/
struct privcurve_s
{
int n; /* number of segments */
int* tag; /* tag[n]: POTRACE_CORNER or POTRACE_CURVETO */
dpoint_t( * c )[3]; /* c[n][i]: control points.
* c[n][0] is unused for tag[n]=POTRACE_CORNER */
/* the remainder of this structure is special to privcurve, and is
* used in EPS debug output and special EPS "short coding". These
* fields are valid only if "alphacurve" is set. */
int alphacurve; /* have the following fields been initialized? */
dpoint_t* vertex; /* for POTRACE_CORNER, this equals c[1] */
double* alpha; /* only for POTRACE_CURVETO */
double* alpha0; /* "uncropped" alpha parameter - for debug output only */
double* beta;
};
typedef struct privcurve_s privcurve_t;
struct sums_s
{
double x;
double y;
double x2;
double xy;
double y2;
};
typedef struct sums_s sums_t;
/* the path structure is filled in with information about a given path
* as it is accumulated and passed through the different stages of the
* Potrace algorithm. Backends only need to read the fcurve and fm
* fields of this data structure, but debugging backends may read
* other fields. */
struct potrace_privpath_s
{
int len;
point_t* pt; /* pt[len]: path as extracted from bitmap */
int* lon; /* lon[len]: (i,lon[i]) = longest straight line from i */
int x0, y0; /* origin for sums */
sums_t* sums; /* sums[len+1]: cache for fast summing */
int m; /* length of optimal polygon */
int* po; /* po[m]: optimal polygon */
privcurve_t curve; /* curve[m]: array of curve elements */
privcurve_t ocurve; /* ocurve[om]: array of curve elements */
privcurve_t* fcurve; /* final curve: this points to either curve or
* ocurve. Do not free this separately. */
};
typedef struct potrace_privpath_s potrace_privpath_t;
/* shorter names */
typedef potrace_privpath_t privpath_t;
typedef potrace_path_t path_t;
path_t* path_new( void );
void path_free( path_t* p );
void pathlist_free( path_t* plist );
int privcurve_init( privcurve_t* curve, int n );
void privcurve_to_curve( privcurve_t* pc, potrace_curve_t* c );
#endif /* CURVE_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* $Id: decompose.h 147 2007-04-09 00:44:09Z selinger $ */
#ifndef DECOMPOSE_H
#define DECOMPOSE_H
#include "potracelib.h"
#include "progress.h"
int bm_to_pathlist( const potrace_bitmap_t* bm,
path_t** plistp,
const potrace_param_t* param,
progress_t* progress );
#endif /* DECOMPOSE_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
/* $Id: greymap.h 147 2007-04-09 00:44:09Z selinger $ */
#ifndef PGM_H
#define PGM_H
#include <stdio.h>
/* internal format for greymaps. Note: in this format, rows are
ordered from bottom to top. The pixels in each row are given from
left to right. */
struct greymap_s {
int w; /* width, in pixels */
int h; /* height, in pixels */
signed short int *map; /* raw data, w*h values */
};
typedef struct greymap_s greymap_t;
/* macros for accessing pixel at index (x,y). Note that the origin is
in the *lower* left corner. U* macros omit the bounds check. */
#define gm_index(gm, x, y) (&(gm)->map[(x)+(y)*(gm)->w])
#define gm_safe(gm, x, y) ((int)(x)>=0 && (int)(x)<(gm)->w && (int)(y)>=0 && (int)(y)<(gm)->h)
#define gm_bound(x, m) ((x)<0 ? 0 : (x)>=(m) ? (m)-1 : (x))
#define GM_UGET(gm, x, y) (*gm_index(gm, x, y))
#define GM_UINC(gm, x, y, b) (*gm_index(gm, x, y) += (short int)(b))
#define GM_UINV(gm, x, y) (*gm_index(gm, x, y) = 255 - *gm_index(gm, x, y))
#define GM_UPUT(gm, x, y, b) (*gm_index(gm, x, y) = (short int)(b))
#define GM_GET(gm, x, y) (gm_safe(gm, x, y) ? GM_UGET(gm, x, y) : 0)
#define GM_INC(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UINC(gm, x, y, b) : 0)
#define GM_INV(gm, x, y) (gm_safe(gm, x, y) ? GM_UINV(gm, x, y) : 0)
#define GM_PUT(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UPUT(gm, x, y, b) : 0)
#define GM_BGET(gm, x, y) GM_UGET(gm, gm_bound(x, gm->w), gm_bound(y, gm->h))
/* modes for cutting off out-of-range values. The following names
refer to winding numbers. I.e., make a pixel black if winding
number is nonzero, odd, or positive, respectively. We assume that 0
winding number corresponds to white (255). */
#define GM_MODE_NONZERO 1
#define GM_MODE_ODD 2
#define GM_MODE_POSITIVE 3
#define GM_MODE_NEGATIVE 4
extern const char *gm_read_error;
greymap_t *gm_new(int w, int h);
greymap_t *gm_dup(greymap_t *gm);
void gm_free(greymap_t *gm);
void gm_clear(greymap_t *gm, int b);
int gm_read(FILE *f, greymap_t **gmp);
int gm_writepgm(FILE *f, greymap_t *gm, char *comment, int raw, int mode, double gamma);
int gm_print(FILE *f, greymap_t *gm);
#endif /* PGM_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* this header file contains some platform dependent stuff */
#ifndef PLATFORM_H
#define PLATFORM_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* in Windows, set all file i/o to binary */
#ifdef __MINGW32__
#include <fcntl.h>
unsigned int _CRT_fmode = _O_BINARY;
#endif
#ifdef __CYGWIN__
#include <fcntl.h>
#include <io.h>
static inline void platform_init( void )
{
setmode( 0, O_BINARY );
setmode( 1, O_BINARY );
}
#else
static inline void platform_init( void )
{
/* NOP */
}
#endif
#endif /* PLATFORM_H */
#define POTRACELIB_VERSION "potracelib 1.8"
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details.
*/
#include <stdlib.h>
#include <string.h>
#include "potracelib.h"
#include "curve.h"
#include "decompose.h"
#include "trace.h"
#include "progress.h"
#include "potrace_version.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* default parameters */
static const potrace_param_t param_default =
{
2, /* turdsize */
POTRACE_TURNPOLICY_MINORITY, /* turnpolicy */
1.0, /* alphamax */
1, /* opticurve */
0.2, /* opttolerance */
{
NULL, /* callback function */
NULL, /* callback data */
0.0, 1.0, /* progress range */
0.0, /* granularity */
},
};
/* Return a fresh copy of the set of default parameters, or NULL on
* failure with errno set. */
potrace_param_t* potrace_param_default( void )
{
potrace_param_t* p;
p = (potrace_param_t*) malloc( sizeof(potrace_param_t) );
if( !p )
{
return NULL;
}
memcpy( p, &param_default, sizeof(potrace_param_t) );
return p;
}
/* On success, returns a Potrace state st with st->status ==
* POTRACE_STATUS_OK. On failure, returns NULL if no Potrace state
* could be created (with errno set), or returns an incomplete Potrace
* state (with st->status == POTRACE_STATUS_INCOMPLETE). Complete or
* incomplete Potrace state can be freed with potrace_state_free(). */
potrace_state_t* potrace_trace( const potrace_param_t* param, const potrace_bitmap_t* bm )
{
int r;
path_t* plist = NULL;
potrace_state_t* st;
progress_t prog;
progress_t subprog;
/* prepare private progress bar state */
prog.callback = param->progress.callback;
prog.data = param->progress.data;
prog.min = param->progress.min;
prog.max = param->progress.max;
prog.epsilon = param->progress.epsilon;
prog.d_prev = param->progress.min;
/* allocate state object */
st = (potrace_state_t*) malloc( sizeof(potrace_state_t) );
if( !st )
{
return NULL;
}
progress_subrange_start( 0.0, 0.1, &prog, &subprog );
/* process the image */
r = bm_to_pathlist( bm, &plist, param, &subprog );
if( r )
{
free( st );
return NULL;
}
st->status = POTRACE_STATUS_OK;
st->plist = plist;
st->priv = NULL; /* private state currently unused */
progress_subrange_end( &prog, &subprog );
progress_subrange_start( 0.1, 1.0, &prog, &subprog );
/* partial success. */
r = process_path( plist, param, &subprog );
if( r )
{
st->status = POTRACE_STATUS_INCOMPLETE;
}
progress_subrange_end( &prog, &subprog );
return st;
}
/* free a Potrace state, without disturbing errno. */
void potrace_state_free( potrace_state_t* st )
{
pathlist_free( st->plist );
free( st );
}
/* free a parameter list, without disturbing errno. */
void potrace_param_free( potrace_param_t* p )
{
free( p );
}
const char* potrace_version( void )
{
return POTRACELIB_VERSION;
}
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
#ifndef POTRACELIB_H
#define POTRACELIB_H
/* this file defines the API for the core Potrace library. For a more
* detailed description of the API, see doc/potracelib.txt */
/* ---------------------------------------------------------------------- */
/* tracing parameters */
/* turn policies */
#define POTRACE_TURNPOLICY_BLACK 0
#define POTRACE_TURNPOLICY_WHITE 1
#define POTRACE_TURNPOLICY_LEFT 2
#define POTRACE_TURNPOLICY_RIGHT 3
#define POTRACE_TURNPOLICY_MINORITY 4
#define POTRACE_TURNPOLICY_MAJORITY 5
#define POTRACE_TURNPOLICY_RANDOM 6
/* structure to hold progress bar callback data */
struct potrace_progress_s
{
void (* callback)( double progress, void* privdata ); /* callback fn */
void* data; /* callback function's private data */
double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */
double epsilon; /* granularity: can skip smaller increments */
};
typedef struct potrace_progress_s potrace_progress_t;
/* structure to hold tracing parameters */
struct potrace_param_s
{
int turdsize; /* area of largest path to be ignored */
int turnpolicy; /* resolves ambiguous turns in path decomposition */
double alphamax; /* corner threshold */
int opticurve; /* use curve optimization? */
double opttolerance; /* curve optimization tolerance */
potrace_progress_t progress; /* progress callback function */
};
typedef struct potrace_param_s potrace_param_t;
/* ---------------------------------------------------------------------- */
/* bitmaps */
/* native word size */
typedef unsigned long potrace_word;
/* Internal bitmap format. The n-th scanline starts at scanline(n) =
* (map + n*dy). Raster data is stored as a sequence of potrace_words
* (NOT bytes). The leftmost bit of scanline n is the most significant
* bit of scanline(n)[0]. */
struct potrace_bitmap_s
{
int w, h; /* width and height, in pixels */
int dy; /* words per scanline (not bytes) */
potrace_word* map; /* raw data, dy*h words */
};
typedef struct potrace_bitmap_s potrace_bitmap_t;
/* ---------------------------------------------------------------------- */
/* curves */
/* point */
struct potrace_dpoint_s
{
double x, y;
};
typedef struct potrace_dpoint_s potrace_dpoint_t;
/* segment tags */
#define POTRACE_CURVETO 1
#define POTRACE_CORNER 2
/* closed curve segment */
struct potrace_curve_s
{
int n; /* number of segments */
int* tag; /* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
potrace_dpoint_t( * c )[3]; /* c[n][3]: control points.
* c[n][0] is unused for tag[n]=POTRACE_CORNER */
};
typedef struct potrace_curve_s potrace_curve_t;
/* Linked list of signed curve segments. Also carries a tree structure. */
struct potrace_path_s
{
int area; /* area of the bitmap path */
int sign; /* '+' or '-', depending on orientation */
potrace_curve_t curve; /* this path's vector data */
struct potrace_path_s* next; /* linked list structure */
struct potrace_path_s* childlist; /* tree structure */
struct potrace_path_s* sibling; /* tree structure */
struct potrace_privpath_s* priv; /* private state */
};
typedef struct potrace_path_s potrace_path_t;
/* ---------------------------------------------------------------------- */
/* Potrace state */
#define POTRACE_STATUS_OK 0
#define POTRACE_STATUS_INCOMPLETE 1
struct potrace_state_s
{
int status;
potrace_path_t* plist; /* vector data */
struct potrace_privstate_s* priv; /* private state */
};
typedef struct potrace_state_s potrace_state_t;
/* ---------------------------------------------------------------------- */
/* API functions */
/* get default parameters */
potrace_param_t* potrace_param_default( void );
/* free parameter set */
void potrace_param_free( potrace_param_t* p );
/* trace a bitmap*/
potrace_state_t* potrace_trace( const potrace_param_t* param,
const potrace_bitmap_t* bm );
/* free a Potrace state */
void potrace_state_free( potrace_state_t* st );
/* return a static plain text version string identifying this version
* of potracelib */
const char* potrace_version( void );
#endif /* POTRACELIB_H */
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* operations on potrace_progress_t objects, which are defined in
* potracelib.h. Note: the code attempts to minimize runtime overhead
* when no progress monitoring was requested. It also tries to
* minimize excessive progress calculations beneath the "epsilon"
* threshold. */
#ifndef PROGRESS_H
#define PROGRESS_H
/* structure to hold progress bar callback data */
struct progress_s
{
void (* callback)( double progress, void* privdata ); /* callback fn */
void* data; /* callback function's private data */
double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */
double epsilon; /* granularity: can skip smaller increments */
double b; /* upper limit of subrange in superrange units */
double d_prev; /* previous value of d */
};
typedef struct progress_s progress_t;
/* notify given progress object of current progress. Note that d is
* given in the 0.0-1.0 range, which will be scaled and translated to
* the progress object's range. */
static inline void progress_update( double d, progress_t* prog )
{
double d_scaled;
if( prog->callback != NULL )
{
d_scaled = prog->min * (1 - d) + prog->max * d;
if( d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon )
{
prog->callback( prog->min * (1 - d) + prog->max * d, prog->data );
prog->d_prev = d_scaled;
}
}
}
/* start a subrange of the given progress object. The range is
* narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
* is below granularity threshold, disable further subdivisions. */
static inline void progress_subrange_start( double a,
double b,
const progress_t* prog,
progress_t* sub )
{
double min, max;
if( prog->callback == NULL )
{
sub->callback = NULL;
return;
}
min = prog->min * (1 - a) + prog->max * a;
max = prog->min * (1 - b) + prog->max * b;
if( max - min < prog->epsilon )
{
sub->callback = NULL; /* no further progress info in subrange */
sub->b = b;
return;
}
sub->callback = prog->callback;
sub->data = prog->data;
sub->epsilon = prog->epsilon;
sub->min = min;
sub->max = max;
sub->d_prev = prog->d_prev;
return;
}
static inline void progress_subrange_end( progress_t* prog, progress_t* sub )
{
if( prog->callback != NULL )
{
if( sub->callback == NULL )
{
progress_update( sub->b, prog );
}
else
{
prog->d_prev = sub->d_prev;
}
}
}
#endif /* PROGRESS_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* $Id: render.h 147 2007-04-09 00:44:09Z selinger $ */
#ifndef RENDER_H
#define RENDER_H
#include "greymap.h"
struct render_s
{
greymap_t* gm;
double x0, y0, x1, y1;
int x0i, y0i, x1i, y1i;
double a0, a1;
int* incrow_buf;
};
typedef struct render_s render_t;
render_t* render_new( greymap_t* gm );
void render_free( render_t* rm );
void render_close( render_t* rm );
void render_moveto( render_t* rm, double x, double y );
void render_lineto( render_t* rm, double x, double y );
void render_curveto( render_t* rm,
double x2,
double y2,
double x3,
double y3,
double x4,
double y4 );
#endif /* RENDER_H */
This diff is collapsed.
/* Copyright (C) 2001-2007 Peter Selinger.
* This file is part of Potrace. It is free software and it is covered
* by the GNU General Public License. See the file COPYING for details. */
/* $Id: trace.h 147 2007-04-09 00:44:09Z selinger $ */
#ifndef TRACE_H
#define TRACE_H
#include "potracelib.h"
#include "progress.h"
int process_path( path_t* plist, const potrace_param_t* param, progress_t* progress );
#endif /* TRACE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment