summaryrefslogtreecommitdiff
path: root/scanin/scanrd_.h
diff options
context:
space:
mode:
Diffstat (limited to 'scanin/scanrd_.h')
-rw-r--r--scanin/scanrd_.h321
1 files changed, 321 insertions, 0 deletions
diff --git a/scanin/scanrd_.h b/scanin/scanrd_.h
new file mode 100644
index 0000000..52d6368
--- /dev/null
+++ b/scanin/scanrd_.h
@@ -0,0 +1,321 @@
+
+/*
+ * Argyll Color Correction System
+ *
+ * Scanrd: Scan chart reader
+ * This is the core chart recognition code.
+ * Private H file for scanrd.c
+ *
+ * Author: Graeme W. Gill
+ * Date: 28/9/96
+ *
+ * Copyright 1995, 1996, 2008, Graeme W. Gill
+ * All rights reserved.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#include "scanrd.h" /* Include public structure */
+
+#include "../h/llist.h" /* Linked list macros */
+
+#ifndef M_PI
+#define M_PI 3.1415926535897932384626433832795028841971693993751
+#endif
+#ifndef M_PI_2
+#define M_PI_2 (0.5 * M_PI)
+#endif
+#ifndef M_PI_4
+#define M_PI_4 (0.25 * M_PI)
+#endif
+#ifndef M_PI_3_4
+#define M_PI_3_4 (0.75 * M_PI)
+#endif
+#ifndef M_2_PI
+#define M_2_PI (2.0/M_PI)
+#endif
+#ifndef M_SQRT_2
+#define M_SQRT_2 1.4142135623730950488016887242096980785696718753769
+#endif
+
+#define DEG(aa) ((aa) * 180.0/M_PI)
+
+#define iabs(a) ((a) < 0 ? -(a) : (a))
+
+#define MXDE 4 /* Maximum useful pixel depth */
+
+/* A run of points at a given y, in a group */
+typedef struct {
+ int y,lx,hx; /* Region covers values of lx <= x < hx */
+ } run;
+
+/* Structure to hold the points that may make up a line */
+struct _points {
+ int no; /* number of coordinates (indexed from ca) */
+ int mxno; /* Maximum number that can be allocated from ca */
+ run *r; /* point runs array */
+ int pn; /* Diagnostic serial no */
+ LINKSTRUCT(struct _points); /* Linked list structure */
+
+ /* Line stats */
+ int flag;
+ int nop; /* Number of points */
+ double mw,len; /* mean width, length */
+ double mx,my; /* Mean point */
+ double a; /* Angle */
+ double ca; /* Constrained Angle (constrained to 90 degrees about 0 */
+ double x1,y1,x2,y2; /* Start/end point of fitted line */
+
+ double pmx, pmy; /* Raster (Perspective affected) mean point */
+ double px1, py1, px2, py2; /* Raster (Perspective affected) line start/end points */
+ struct _points *opt; /* Next in improvement list */
+}; typedef struct _points points;
+
+#define F_LINESTATS 0x01 /* Line stats valid */
+#define F_VALID 0x02 /* Line passes valid criteria */
+#define F_LONGENOUGH 0x04 /* Line is long enough to be included in angle calc */
+#define F_IMPROVE 0x08 /* Line was used to improve fit */
+
+/* Structure to hold an aggregation region description */
+struct _region {
+ int lx,hx; /* Region covers values of lx <= x < hx */
+ points *p; /* Head of points linked list associated with region */
+}; typedef struct _region region;
+
+/* Structure to hold a 2D real point */
+struct _point {
+ double x,y;
+}; typedef struct _point point;
+
+/* Structure to hold one entry in an edge list */
+struct _epoint {
+ double pos; /* Position of entry along edge */
+ double len; /* (Maximum normalized) Total length */
+ double p1,p2; /* Start and end of line in orthogonal direction */
+ double ccount; /* (Maximum normalized) Crossing count */
+ struct _points *opt; /* Linked list of feature lines to optimize to */
+ int nopt;
+}; typedef struct _epoint epoint;
+
+/* Structure of an edge list */
+struct _elist {
+ epoint *a; /* Array of edge points */
+ int c; /* Count */
+ double lennorm; /* Total of max. normalized lengths of edge list */
+}; typedef struct _elist elist;
+
+#define INIT_ELIST(e) { \
+ e.a = NULL; \
+ e.c = 0; \
+ e.lennorm = 0.0; \
+}
+
+/* An edge correlation return structure */
+typedef struct {
+ double cc,off,scale;
+} ematch;
+
+
+/* An integer point */
+struct _ipoint {
+ int x,y;
+}; typedef struct _ipoint ipoint;
+
+/* An edge scan structure */
+struct _escan {
+ int e[4]; /* Indexes of points for left or right sides */
+ int i; /* Index of current pair */
+ int ev,k1,k2; /* Bresenham constants */
+ int y; /* Current y value */
+ int xi,x; /* X increment, current x value */
+}; typedef struct _escan escan;
+
+/* Structure of a sample box */
+#define SBOX_NAME_SZ 20
+struct _sbox {
+ int diag; /* Non-zero if diagnostic only */
+ char name[SBOX_NAME_SZ]; /* Box name (usualy letter number coordinate) */
+ double xpt[3]; /* Lab expected value. L < 0 if not valid */
+ double x1,y1,x2,y2; /* Reference box corner points */
+ ipoint p[4]; /* Transformed sample box coordinates */
+ int active; /* Flag to indicate box is active in scan */
+ int ymin,ymax; /* Min and nmax y values */
+ escan l,r; /* left and right edge scan structures */
+
+ unsigned long *ps[MXDE]; /* Pixel value histogram arrays (256 or 65536) */
+ /* Pixel values just scanned, or from best rotation */
+ double mP[MXDE]; /* Mean Pixel values (0.0 - 255.0) */
+ double sdP[MXDE]; /* Standard deviations */
+ double P[MXDE]; /* Output Pixel values */
+ unsigned int cnt; /* Total pixels in cell */
+ LINKSTRUCT(struct _sbox); /* Active edge linked list structure */
+
+ /* Pixel values for alternate rotations, created if we have expected values */
+ struct {
+ double mP[MXDE]; /* Mean Pixel values (0.0 - 255.0) */
+ double sdP[MXDE]; /* Standard deviations */
+ double P[MXDE]; /* Robust mean Output Pixel values (0.0 .. 255.0) */
+ unsigned int cnt; /* Total pixels in cell */
+ } rot[4];
+
+ }; typedef struct _sbox sbox;
+
+/* The private scanrd object */
+struct _scanrd_ {
+ /* Public part of structure */
+ scanrd public;
+
+ /* Private variables */
+ int flags; /* Operation/diagnostic flags */
+ int verb; /* verbosity level */
+ /* 0 = none */
+ /* 1 = warnings */
+ /* 2 = minimum */
+ /* 3 = per patch */
+ /* 3 = patch scan details */
+ /* 5 = per line */
+ /* 7 = matching attempts */
+ /* 8 = per pixel */
+
+ unsigned int errv; /* Error value */
+ char errm[200]; /* Error message */
+
+ double gammav; /* Approximate gamma encoding of input image */
+ int width,height; /* With and height of raster in pixels */
+ int depth; /* Useful pixel plane depth */
+ int tdepth; /* Total pixel plane depth */
+ int bpp; /* Bit precision per pixel, 8 or 16 */
+ int bypp; /* Bytes per pixel, either 1 or 2 */
+
+ unsigned char *out; /* Diagnostic output raster array */
+
+ int noslines; /* Number of lines with valid stats */
+ int novlines; /* Number of valid lines */
+ points *gdone; /* Head of done point linked list groups */
+
+ double ppc[4]; /* Partial perspective correction values. */
+ /* persp() applies perspective distortion, */
+ /* invpersp() applies perspective correction. */
+
+ double irot; /* Base image rotation value in radians (clockwize) */
+ int norots; /* Number of rotations to explore */
+ int crot; /* Current or best rotation being scanned */
+ struct {
+ double irot; /* Image rotation value in radians (clockwize) for this rotation */
+ double ixoff,iyoff,ixscale,iyscale; /* Image offset and scale factors */
+ double cc; /* Edge match correlation */
+ double xcc; /* Expected value correlation, smaller is better */
+ } rots[4];
+
+ double ptrans[8]; /* Combined transform of partial perspective, */
+ /* irot, i[xy]off and i[xy]scale. */
+ /* Use ptrans(ptrans[]) to transform from reference to raster. */
+ double iptrans[8]; /* Inverse transform of ptrans[] */
+ /* Use ptrans(iptrans[]) to transform from raster to reference */
+
+ elist xelist, yelist; /* X and Y raster edge lists array */
+ elist ixelist, iyelist; /* Inverted direction X and Y raster edge lists array */
+
+ elist rxelist, ryelist; /* X and Y .cht reference edge lists array */
+
+ double rbox_shrink; /* Reference box shrink factor */
+ int xpt; /* NZ if got expected reference values */
+
+ double fid[8]; /* Four fiducial locations, typicall clockwise from top left */
+ double fidsize; /* Fiducial diagnostic cross size */
+ double havefids; /* NZ if there are fiducials */
+ int nsbox; /* Number of sample boxes */
+ sbox *sboxes; /* List of sample boxes */
+ sbox **sbstart; /* Sorted start list */
+ sbox **sbend; /* Sorted end list */
+ int csi,cei; /* Current start/end indexes */
+ sbox *alist; /* Active list during pixel value sampling */
+
+ double adivval; /* Overall average divider value */
+ int divc; /* Average divide count */
+
+ int next_read; /* Next box value to read */
+
+ char *refname; /* Path of reference file */
+
+ int inited; /* Gamma and regions inited */
+ unsigned short gamma[256 * 256]; /* Inverse gamma lookup */
+ region *vrego, *vregn; /* Old and New region for delX or vertical lines */
+ int no_vo, no_vn; /* Number of regions in array */
+ region *hrego, *hregn; /* Old and New region for delY or horizontal lines */
+ int no_ho, no_hn; /* Number of regions in array */
+ double th; /* Color change threshold */
+ double divval; /* Current orthogonal divider value */
+
+ /* aa line stuff */
+ int aa_inited; /* Non-zero if anti-aliased line tables are inited */
+ int *coverage; /* Coverage lookup array */
+ int covercells;
+ int covershift;
+ int Pmax;
+ int adj_pixinc[4]; /* Pixel address increments for 4 directions */
+ int diag_pixinc[4];
+ int orth_pixinc[4];
+
+ /*** Callbacks ***/
+
+ int (*read_line)(void *fdata, int y, char *dst);
+ /* Read line of source file, non-zero on error */
+ void *fdata; /* Opaque data for callback */
+
+ int (*write_line)(void *ddata, int y, char *src);
+ /* Write RGB line of diag file, non-zero on error */
+ void *ddata; /* Opaque data for callback */
+
+}; typedef struct _scanrd_ scanrd_;
+
+/*************************************************************************/
+/* Heapsort macro */
+
+/* HEAP_COMPARE(A,B) returns true if A < B */
+#define HEAPSORT(TYPE,ARRAY,NUMBER) \
+ { \
+ TYPE *hs_ncb = ARRAY; \
+ int hs_l,hs_j,hs_ir,hs_i; \
+ TYPE hs_rra; \
+ \
+ if (NUMBER >= 2) \
+ { \
+ hs_l = NUMBER >> 1; \
+ hs_ir = NUMBER-1; \
+ for (;;) \
+ { \
+ if (hs_l > 0) \
+ hs_rra = hs_ncb[--hs_l]; \
+ else \
+ { \
+ hs_rra = hs_ncb[hs_ir]; \
+ hs_ncb[hs_ir] = hs_ncb[0]; \
+ if (--hs_ir == 0) \
+ { \
+ hs_ncb[0] = hs_rra; \
+ break; \
+ } \
+ } \
+ hs_i = hs_l; \
+ hs_j = hs_l+hs_l+1; \
+ while (hs_j <= hs_ir) \
+ { \
+ if (hs_j < hs_ir && HEAP_COMPARE(hs_ncb[hs_j],hs_ncb[hs_j+1])) \
+ hs_j++; \
+ if (HEAP_COMPARE(hs_rra,hs_ncb[hs_j])) \
+ { \
+ hs_ncb[hs_i] = hs_ncb[hs_j]; \
+ hs_i = hs_j; \
+ hs_j = hs_j+hs_j+1; \
+ } \
+ else \
+ hs_j = hs_ir + 1; \
+ } \
+ hs_ncb[hs_i] = hs_rra; \
+ } \
+ } \
+ }
+
+/*************************************************************************/
+