From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- scanin/scanrd_.h | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 scanin/scanrd_.h (limited to 'scanin/scanrd_.h') 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; \ + } \ + } \ + } + +/*************************************************************************/ + -- cgit v1.2.3