1 /** 2 * libdmtx - Data Matrix Encoding/Decoding Library 3 * Copyright 2010 Mike Laughton. All rights reserved. 4 * 5 * See LICENSE file in the main project directory for full 6 * terms of use and distribution. 7 * 8 * Contact: Mike Laughton <mike@dragonflylogic.com> 9 * 10 * \file multi_test.h 11 */ 12 13 #include <SDL/SDL.h> 14 #include "../../dmtx.h" 15 16 #define max(N,M) ((N > M) ? N : M) 17 #define min(N,M) ((N < M) ? N : M) 18 #define OPPOSITE_SIGNS(a,b) (a != 0 && b != 0 && ((a > 0) != (b > 0))) 19 20 #define LOCAL_SIZE 64 21 #define MAXIMA_SORT_MAX_COUNT 8 22 #define ANGLE_SORT_MAX_COUNT 8 23 #define TIMING_SORT_MAX_COUNT 8 24 25 #define NFFT 64 /* FFT input size */ 26 #define HOUGH_D_EXTENT 64 27 #define HOUGH_PHI_EXTENT 128 28 29 /* Layout constants */ 30 #define CTRL_COL1_X 380 31 #define CTRL_COL2_X 445 32 #define CTRL_COL3_X 510 33 #define CTRL_COL4_X 575 34 #define CTRL_ROW1_Y 0 35 #define CTRL_ROW2_Y 65 36 #define CTRL_ROW3_Y 130 37 #define CTRL_ROW4_Y 195 38 #define CTRL_ROW5_Y 260 39 #define CTRL_ROW6_Y 325 40 #define CTRL_ROW7_Y 390 41 42 #define MODULE_LOW 0 43 #define MODULE_HIGH 1 44 #define MODULE_UNKNOWN 2 45 46 #define RotateCCW(N) ((N < 8) ? (N << 1) : 1) 47 #define RotateCW(N) ((N > 1) ? (N >> 1) : 8) 48 49 typedef struct UserOptions_struct { 50 const char *imagePath; 51 } UserOptions; 52 53 typedef struct AppState_struct { 54 int windowWidth; 55 int windowHeight; 56 int activeExtent; 57 DmtxImage *imgActive; 58 DmtxImage *imgFull; 59 DmtxImage *dmtxImage; 60 DmtxBoolean autoNudge; 61 int displayEdge; 62 DmtxBoolean displayVanish; 63 DmtxBoolean displayTiming; 64 DmtxBoolean displayZXings; 65 DmtxBoolean printValues; 66 Sint16 imageLocX; 67 Sint16 imageLocY; 68 Sint16 imageOffsetX; /* X offset of right-handed image origin from screen origin */ 69 Sint16 imageOffsetY; /* Y offset of right-handed image origin from screen origin */ 70 Sint16 localOffsetX; /* X offset of active area */ 71 Sint16 localOffsetY; /* Y offset of active area */ 72 Uint8 leftButton; 73 Uint8 rightButton; 74 Uint16 pointerX; 75 Uint16 pointerY; 76 DmtxBoolean quit; 77 SDL_Surface *picture; 78 SDL_Surface *screen; 79 SDL_Surface *local; 80 SDL_Surface *localTmp; 81 } AppState; 82 83 typedef enum { 84 DmtxEdgeVertical, 85 DmtxEdgeBackslash, 86 DmtxEdgeHorizontal, 87 DmtxEdgeSlash 88 } DmtxEdgeType; 89 90 typedef enum { 91 DmtxOctantTop = 0x01, 92 DmtxOctantLeft = 0x01 << 1, 93 DmtxOctantBottom = 0x01 << 2, 94 DmtxOctantRight = 0x01 << 3, 95 DmtxOctantTopLeft = (DmtxOctantTop | DmtxOctantLeft), 96 DmtxOctantBottomLeft = (DmtxOctantBottom | DmtxOctantLeft), 97 DmtxOctantBottomRight = (DmtxOctantBottom | DmtxOctantRight), 98 DmtxOctantTopRight = (DmtxOctantTop | DmtxOctantRight) 99 } DmtxOctantType; 100 101 typedef struct DmtxValueGrid_struct DmtxValueGrid; 102 struct DmtxValueGrid_struct { 103 int width; 104 int height; 105 int type; 106 int *value; 107 DmtxValueGrid *ref; 108 }; 109 110 typedef struct DmtxSobel_struct DmtxSobel; 111 struct DmtxSobel_struct { 112 DmtxValueGrid *v; 113 DmtxValueGrid *b; 114 DmtxValueGrid *h; 115 DmtxValueGrid *s; 116 }; 117 118 typedef struct DmtxAccel_struct DmtxAccel; 119 struct DmtxAccel_struct { 120 DmtxValueGrid *vv; 121 DmtxValueGrid *vb; 122 DmtxValueGrid *hb; 123 DmtxValueGrid *hh; 124 DmtxValueGrid *hs; 125 DmtxValueGrid *vs; 126 }; 127 128 struct ZeroCrossing_struct { 129 int iCol; 130 int iRow; 131 int mag; 132 double x; 133 double y; 134 }; 135 typedef struct ZeroCrossing_struct ZeroCrossing; 136 137 typedef struct DmtxHoughBucket_struct DmtxHoughBucket; 138 struct DmtxHoughBucket_struct { 139 int phi; 140 int d; 141 int val; 142 }; 143 144 typedef struct DmtxHoughLocal_struct DmtxHoughLocal; 145 struct DmtxHoughLocal_struct { 146 int xOrigin; 147 int yOrigin; 148 int dOrigin[128]; 149 int bucket[64][128]; /* [rows][cols] */ /* later change to 65 */ 150 }; 151 152 typedef struct DmtxHough_struct DmtxHough; 153 struct DmtxHough_struct { 154 int rows; 155 int cols; 156 int count; 157 DmtxHoughLocal *line; 158 DmtxHoughLocal *maxima; 159 DmtxHoughLocal *vanish; 160 }; 161 162 typedef struct HoughMaximaSort_struct { 163 int count; 164 int mag[MAXIMA_SORT_MAX_COUNT]; 165 } HoughMaximaSort; 166 167 typedef struct VanishPointSort_struct { 168 int count; 169 DmtxHoughBucket bucket[ANGLE_SORT_MAX_COUNT]; 170 } VanishPointSort; 171 172 typedef struct Timing_struct { 173 int phi; 174 double shift; 175 double period; 176 double mag; 177 } Timing; 178 179 struct DmtxTimingSort_struct { 180 int count; 181 Timing timing[TIMING_SORT_MAX_COUNT]; 182 }; 183 typedef struct DmtxTimingSort_struct DmtxTimingSort; 184 185 typedef struct DmtxOrient_struct DmtxOrient; 186 struct DmtxOrient_struct { 187 /* add supporting values used to build tranformation matrices here */ 188 DmtxMatrix3 raw2fitLocal; 189 DmtxMatrix3 raw2fit; 190 DmtxMatrix3 fit2rawLocal; 191 DmtxMatrix3 fit2raw; 192 }; 193 194 typedef struct AlignmentGrid_struct { 195 int rowCount; 196 int colCount; 197 DmtxMatrix3 raw2fitActive; 198 DmtxMatrix3 raw2fitFull; 199 DmtxMatrix3 fit2rawActive; 200 DmtxMatrix3 fit2rawFull; 201 } AlignmentGrid; 202 203 typedef struct GridRegion_struct { 204 AlignmentGrid grid; 205 int x; 206 int y; 207 int width; 208 int height; 209 int sizeIdx; 210 int onColor; 211 int offColor; 212 int finderSides; 213 int contrast; 214 } GridRegion; 215 216 typedef struct RegionLines_struct { 217 int gridCount; 218 Timing timing; 219 double dA, dB; 220 DmtxRay2 line[2]; 221 } RegionLines; 222 223 struct DmtxRegionSides_struct { 224 DmtxRay2 top; 225 DmtxRay2 left; 226 DmtxRay2 bottom; 227 DmtxRay2 right; 228 }; 229 typedef struct DmtxRegionSides_struct DmtxRegionSides; 230 231 /* All values in GridRegionGrowth should be negative because list 232 * is combined with the positive values of DmtxSymbolSize enum */ 233 typedef enum { 234 GridRegionGrowthUp = -5, 235 GridRegionGrowthLeft = -4, 236 GridRegionGrowthDown = -3, 237 GridRegionGrowthRight = -2, 238 GridRegionGrowthError = -1 239 } GridRegionGrowth; 240 241 typedef enum { 242 DmtxBarNone = 0x00, 243 DmtxBarTiming = 0x01 << 0, 244 DmtxBarFinder = 0x01 << 1, 245 DmtxBarInterior = 0x01 << 2, 246 DmtxBarExterior = 0x01 << 3 247 } DmtxBarType; 248 249 /* Only used internally */ 250 typedef struct ColorTally_struct { 251 int evnCount; 252 int oddCount; 253 int evnColor; 254 int oddColor; 255 } ColorTally; 256 257 struct StripStats_struct { 258 int jumps; 259 int surprises; 260 int finderErrors; 261 int timingErrors; 262 int contrast; 263 int finderBest; 264 int timingBest; 265 }; 266 typedef struct StripStats_struct StripStats; 267 268 struct DmtxCallbacks_struct { 269 void (*dmtxValueGridCallback)(DmtxValueGrid *, int); 270 void (*zeroCrossingCallback)(ZeroCrossing, int); 271 void (*dmtxHoughLocalCallback)(DmtxHoughLocal *, int); 272 void (*vanishPointCallback)(VanishPointSort *, int); 273 void (*timingCallback)(Timing *, Timing *, int); 274 void (*gridCallback)(AlignmentGrid *, int); 275 void (*perimeterCallback)(GridRegion *, DmtxDirection, DmtxBarType); 276 }; 277 typedef struct DmtxCallbacks_struct DmtxCallbacks; 278 279 typedef struct DmtxVectorPair_struct DmtxVectorPair; 280 struct DmtxVectorPair_struct { 281 DmtxVector2 a; 282 DmtxVector2 b; 283 }; 284 285 typedef struct DmtxVanishCorners_struct DmtxVanishCorners; 286 struct DmtxVanishCorners_struct { 287 unsigned char zone; 288 DmtxRay2 lineA; /* XXX consider switching to DmtxVectorPair later? */ 289 DmtxRay2 lineB; 290 }; 291 292 struct DmtxDecode2_struct { 293 DmtxImage *image; 294 DmtxSobel *sobel; 295 DmtxAccel *accel; 296 DmtxHough *hough; 297 DmtxVanishCorners corners[64][128]; /* XXX temporary location */ 298 DmtxCallbacks fn; 299 }; 300 typedef struct DmtxDecode2_struct DmtxDecode2; 301 302 /* Application level functions */ 303 DmtxPassFail HandleArgs(UserOptions *opt, int *argcp, char **argvp[]); 304 AppState InitAppState(void); 305 DmtxImage *CreateDmtxImage(SDL_Surface *sdlImage); 306 void AddFullTransforms(AlignmentGrid *grid); 307 SDL_Surface *SetWindowSize(int windowWidth, int windowHeight); 308 void captureLocalPortion(SDL_Surface *local, SDL_Surface *localTmp, 309 SDL_Surface *picture, SDL_Surface *screen, AppState *state, SDL_Rect imageLoc); 310 DmtxPassFail HandleEvent(SDL_Event *event, AppState *state, 311 SDL_Surface *picture, SDL_Surface **screen); 312 DmtxPassFail NudgeImage(int windowExtent, int pictureExtent, Sint16 *imageLoc); 313 /*static void WriteDiagnosticImage(DmtxDecode *dec, char *imagePath);*/ 314 315 /* Image processing functions */ 316 DmtxPassFail dmtxRegion2FindNext(DmtxDecode2 *dec); 317 DmtxPassFail OrientRegion(DmtxOrient *orient, DmtxHoughBucket v0, DmtxHoughBucket v1, DmtxDecode2 *dec); 318 double UncompactOffset(double d, int phiIdx, int extent); 319 void AddToVanishPointSort(VanishPointSort *sort, DmtxHoughBucket bucket); 320 VanishPointSort dmtxFindVanishPoints(DmtxHoughLocal *vHough); 321 void AddToMaximaSort(HoughMaximaSort *sort, int maximaMag); 322 DmtxHoughBucket GetAngleSumAtPhi(DmtxHoughLocal *local, int phi); 323 void AddToTimingSort(DmtxTimingSort *sort, Timing timing); 324 DmtxTimingSort dmtxFindGridTiming(DmtxHoughLocal *local, VanishPointSort *sort); 325 DmtxRay2 HoughCompactToRay(int phi, double d); 326 DmtxPassFail dmtxBuildGridFromTimings(AlignmentGrid *grid, Timing vp0, Timing vp1); 327 StripStats GenStripPatternStats(unsigned char *strip, int stripLength, int startState, int contrast); 328 GridRegion NudgeStripLimits(GridRegion *region, DmtxDirection side, int nudgeStyle); 329 330 DmtxPassFail dmtxFindRegionWithinGrid(GridRegion *region, AlignmentGrid *grid, DmtxHoughLocal *local, DmtxDecode *dec, DmtxCallbacks *fn); 331 int dmtxReadModuleColor(DmtxImage *img, AlignmentGrid *grid, int symbolRow, int symbolCol, int colorPlane); 332 DmtxBarType TestSideForPattern(GridRegion *region, DmtxImage *img, DmtxDirection side, int offset); 333 DmtxPassFail RegionExpand(GridRegion *region, DmtxDirection dir, DmtxHoughLocal *local, DmtxCallbacks *fn); 334 int dmtxGetSizeIdx(int a, int b); 335 DmtxPassFail RegionUpdateCorners(DmtxMatrix3 fit2raw, DmtxMatrix3 raw2fit, DmtxVector2 p00, DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01); 336 DmtxPassFail dmtxDecodeSymbol(GridRegion *region, DmtxDecode *dec); 337 DmtxPassFail GetOnOffColors(GridRegion *region, const DmtxDecode *dec, int *onColor, int *offColor); 338 ColorTally GetTimingColors(GridRegion *region, const DmtxDecode *dec, int colBeg, int rowBeg, DmtxDirection dir); 339 340 /* Process visualization functions */ 341 void ValueGridCallback(DmtxValueGrid *valueGrid, int id); 342 void ZeroCrossingCallback(ZeroCrossing zXing, int id); 343 void HoughLocalCallback(DmtxHoughLocal *hough, int id); 344 void VanishPointCallback(VanishPointSort *vPoints, int id); 345 void TimingCallback(Timing *timing0, Timing *timing1, int id); 346 void GridCallback(AlignmentGrid *grid, int id); 347 void PerimeterCallback(GridRegion *region, DmtxDirection side, DmtxBarType type); 348 349 void BlitSobelGrid(SDL_Surface *screen, DmtxValueGrid *cache, int x, int y, int screenY, int screenX); 350 void BlitHoughLocal(SDL_Surface *screen, DmtxHoughLocal *hough, int screenY, int screenX); 351 void ShowActiveRegion(SDL_Surface *screen, SDL_Surface *active); 352 void BlitActiveRegion(SDL_Surface *screen, SDL_Surface *active, int zoom, int screenY, int screenX); 353 Uint32 GetPixel(SDL_Surface *surface, int x, int y); 354 void PutPixel(SDL_Surface *surface, int x, int y, Uint32 color); 355 int RayIntersect(double *t, DmtxRay2 p0, DmtxRay2 p1); 356 int IntersectBox(DmtxRay2 ray, DmtxVector2 bb0, DmtxVector2 bb1, DmtxVector2 *p0, DmtxVector2 *p1); 357 void DrawActiveBorder(SDL_Surface *screen, int activeExtent); 358 void DrawLine(SDL_Surface *screen, int baseExtent, int screenX, int screenY, int phi, double d, int displayScale, Uint32 color); 359 void DrawVanishingPoints(SDL_Surface *screen, VanishPointSort *sort, int screenY, int screenX); 360 void DrawTimingDots(SDL_Surface *screen, Timing *timing, int screenY, int screenX); 361 void DrawNormalizedRegion(SDL_Surface *screen, DmtxImage *img, AlignmentGrid *grid, AppState *state, int screenY, int screenX); 362 Sint16 Clamp(Sint16 x, Sint16 xMin, Sint16 extent); 363 void DrawSymbolPreview(SDL_Surface *screen, DmtxImage *img, AlignmentGrid *grid, AppState *state, int screenY, int screenX); 364 void DrawPerimeterPatterns(SDL_Surface *screen, GridRegion *region, AppState *state, DmtxDirection side, DmtxBarType type); 365 void DrawPerimeterSide(SDL_Surface *screen, int x00, int y00, int x11, int y11, int dispModExtent, DmtxDirection side, DmtxBarType type); 366 367 /* dmtxvaluegrid.c */ 368 DmtxValueGrid *dmtxValueGridCreate(int width, int height, int type, DmtxValueGrid *ref); 369 DmtxPassFail dmtxValueGridDestroy(DmtxValueGrid **valueGrid); 370 int dmtxValueGridGetWidth(DmtxValueGrid *valueGrid); 371 int dmtxValueGridGetHeight(DmtxValueGrid *valueGrid); 372 int dmtxValueGridGetValue(DmtxValueGrid *valueGrid, int x, int y); 373 374 /* dmtxsobel.c */ 375 DmtxSobel *SobelCreate(DmtxImage *img); 376 DmtxPassFail SobelDestroy(DmtxSobel **sobel); 377 DmtxPassFail SobelPopulate(DmtxDecode2 *dec); 378 379 DmtxAccel *AccelCreate(DmtxSobel *sobel); 380 DmtxPassFail AccelDestroy(DmtxAccel **accel); 381 DmtxPassFail AccelPopulate(DmtxDecode2 *dec); 382 DmtxPassFail AccelPopulateLocal(DmtxValueGrid *acc); 383 384 /* dmtxdecode2.c */ 385 DmtxDecode2 *dmtxDecode2Create(); 386 DmtxPassFail dmtxDecode2Destroy(DmtxDecode2 **dec); 387 void PopulateVanishBounds(DmtxDecode2 *dec); 388 DmtxVanishCorners GetVanishCorners(int d, int phi); 389 int GetZone(int phiFull, double *distance); 390 DmtxVectorPair GetZoneCornerLocs(DmtxOctantType zone); 391 DmtxPassFail dmtxDecode2SetImage(DmtxDecode2 *dec, DmtxImage *img); 392 DmtxPassFail decode2ReleaseCacheMemory(DmtxDecode2 *dec); 393 394 /* dmtxhough.c */ 395 DmtxHough *HoughCreate(int cols, int rows); 396 DmtxPassFail HoughDestroy(DmtxHough **grid); 397 DmtxPassFail HoughPopulate(DmtxDecode2 *dec); 398 DmtxPassFail LineHoughAccumulate(DmtxHoughLocal *lhRegion, DmtxDecode2 *dec); 399 DmtxPassFail MaximaHoughAccumulate(DmtxHoughLocal *mhRegion, DmtxHoughLocal *lhRegion, DmtxDecode2 *dec); 400 int GetMaximaWeight(DmtxHoughLocal *lhRegion, int phi, int d); 401 DmtxPassFail VanishHoughAccumulate(DmtxHoughLocal *lhRegion, DmtxHoughLocal *vhRegion); 402 int GetVanishBucket(int phiBucket, int phiCompare, int dCompare); 403 ZeroCrossing GetZeroCrossing(DmtxValueGrid *accel, int iCol, int iRow); 404 ZeroCrossing SetZeroCrossingFromIndex(DmtxValueGrid *accel, int aCol, int aRow, double smidg); 405 DmtxPassFail HoughLocalAccumulateEdge(DmtxHoughLocal *local, int phi, ZeroCrossing edge); 406 double HoughGetLocalOffset(double xLoc, double yLoc, int phi); 407 408 extern AppState gState; 409