TODO Items
-----------------------------------------------------------------

version 1.0.0: (planned XX-Oct-2009)
FOCUS: remaining gaps, testing, documentation
  o testsuite: Generate metrics in reproducible format to enable historical tracking
  o testsuite: Investigate option of embedding decoded text into PNG test image comments
  o testsuite: Tests should compare scanned results to embedded PNG comments
  o testsuite: 'make test' writes metrics file
  o testsuite: 'make test' confirms performance

version 0.9.0: (planned XX-Jul-2009)
FOCUS: refactor encoding engine, FNC1, macros
  o libdmtx:   Implement --auto-fast option using algorithm from spec (lighter & faster?)
  o libdmtx:   Structured append reading and writing
  o libdmtx:   Use new Edifact decode function that doesn't assume full triplet
  o libdmtx:   Check ProcessEndOfSymbolTriplet() for same problem fixed in Edifact
  o libdmtx:   Rewrite encoder(s) to not need "twothirdsbits" tracking (fixes multiple bugs)
  o dmtxread:  Print character values (not just codewords) from --codewords (-c) option
  o dmtxread:  Print out image representing "unstretched" barcode
  o dmtxread:  Print color weights based on direction
  o dmtxread:  Diagnostic image shows tighter-fitting outline
  o dmtxread:  Change dmtxread to print out dump of both failed and successful barcodes if requested
  o dmtxread:  Change dmtxread to print out mis-read modules somehow ... additive, subtractive?
               - Build color vector that describes jump from background to foreground color
               - When module is determined to be "off" then add half of color vector
               - When module is determined to be "on" then subtract half of color vector
               - resulting image should clearly show misread modules
  o dmtxwrite: Use MagickCommentImage() to tag images with messages
  o dmtxwrite: Print character values (not just codewords) from --format=c (-fc) option
  o dmtxwrite: Verbose messages describing encoding process
  o testsuite: Implement exhaustive comparison between --auto-fast and --auto-best

version 0.8.0: (planned XX-May-2009)
FOCUS: region detection refinement, multiple barcode scanning, structured append
  o libdmtx:   Consider making "*ProdScaled" default, and unscaled as "Unscaled"
  o libdmtx:   Finish fec integration (encode_rs_char, aLog[], etc...)
  o libdmtx:   Fast Hough fit followed by precision handle fit
  o libdmtx:   Optimizations need to perform multi-barcode scans
  o libdmtx:   Rename outputIdx to outputLength? (Count pad codewords instead of pointer)
  o libdmtx:   Use 100x faster pixel access in PointFlow calculation pass
  o libdmtx:   Use calibration edge alignment to set precise locs for all edges
  o libdmtx:   Implement consistent and robust error handling (errno.h + custom)
  o libdmtx:   Implement structured append symbols
  o dmtxread:  Flatten deeply nested loops in main()
  o dmtxread:  Add true scan timings that factor in linking, startup, image load
  o dmtxwrite: Add support for setting foreground and background colors
  o dmtxquery: Write XML for dmtxquery consumption
  o dmtxquery: Initial working version (parses XML)
  o project:   Any way to ask Magick to filter out GS (and other) warnings?
  o project:   Conditional use of local getopt.c
  o project:   Devise approach for recurring tasks (enabling $Id$, checking SVN commits)

version 0.7.0: (02-Mar-2009)
  x libdmtx:   Fix 64b->32b int assignment warnings
  x libdmtx:   FNC1 and correct upper shift (thanks Robin!)
  x libdmtx:   Support byte-padded row sizes via dmtxImageSetProp()
  x libdmtx:   Move image scaling factors to DmtxDecode
  x libdmtx:   Add DmtxUndefined to replace "-1" for undefined fixes, offset, etc...
  x libdmtx:   Update dmtxImageCreate() parameter options
  x libdmtx:   Switch DmtxFlipNone represent top-down row order
  x libdmtx:   Add dmtxEncodeSetProp() and dmtxEncodeGetProp()
  x libdmtx:   Relocate scan cache from DmtxImage to DmtxDecode
  x libdmtx:   Remove status from DmtxPixelLoc
  x libdmtx:   Configurable pixel packing
  x libdmtx:   Removed DmtxRgb, dmtxcolor.c, DmtxColor3, and DmtxGradient
  x libdmtx:   DmtxTrue/DmtxFalse replaces DMTX_TRUE/DMTX_FALSE
  x libdmtx:   DmtxPass/DmtxFail replaces DMTX_SUCCESS/DMTX_FAILURE
  x libdmtx:   Change all major types to use Create() and Destroy() convention
  x dmtxread:  Option to print extended ASCII as UTF-8 (thanks Robin!)
  x dmtxread:  Fix diagnostic image output
  x dmtxread:  Fix misrepresented capacity in verbose mode
  x dmtxwrite: True vector SVG output bypassing ImageMagick (thanks Richard!)
  x dmtxwrite: Use Magick to write images of major image formats
  x dmtxwrite: Bad option should give short "invalid option -- N; --help for more"
  x dmtxwrite: Use HandleArgs() to capture requests, and process afterward
  x dmtxwrite: Switch to using new dmtxEncodeSetProp() approach
  x wrapper:   New Java wrapper (thanks Pete and Dikran!)
  x wrapper:   New .NET wrapper (thanks Vali and Joe!)
  x project:   Update documentation to reflect API changes
  x project:   Add comment to wiki pages that points to source README
  x project:   Figure out earliest usable Magick version for configure.ac
  x project:   Add simple_test project to libdmtx.sln
  x project:   Rename wiki page to "Windows (VisualC)"
  x project:   Introduce "project" directory for non-autotools platforms
  x project:   Rename "wrappers" directory to "wrapper" for consistency
  x project:   Create a common tasks and release checklist document

version 0.6.0: (23-Nov-2008)
  x libdmtx:   Initial work preparing for custom pixel packing in future
  x libdmtx:   Begin static analysis cleanup with splint
  x libdmtx:   New --disable-dmtxread and --disable-dmtxwrite [Romain]
  x libdmtx:   Ability to specify max/min expected barcode sizes
  x libdmtx:   New edge neighbor tracking (Hough Transform + 2 way edge cache)
  x libdmtx:   Info cache to track scan progress and avoid rescanning pixels
  x libdmtx:   Scan multiple barcodes within an image
  x libdmtx:   Significantly reduced memory footprint
  x libdmtx:   Major reduction in floating point operations
  x dmtxread:  New informative return codes (found, not found, error)
  x dmtxread:  Read input from STDIN
  x dmtxread:  GraphicsMagick support for image reading [Olivier]
  x dmtxread:  JPEG reading support [Ryan]
  x dmtxread:  Diagnostic images display trail left by scanning logic
  x dmtxwrite: Option to write output to STDOUT [Olivier]
  x wrapper:   PHP wrapper now compiles with recent libdmtx
  x wrapper:   New encoding/decoding Ruby wrapper [Romain]
  x project:   Dedicated README.xxx instructions for specific platforms
  x project:   Various improvements for cross platform builds

version 0.5.2: (04-Sep-2008)
  x libdmtx:   Move SetRangeLimit and SetScanRegion into library
  x libdmtx:   Replace DMTXUTIL_SUCCESS/ERROR with DMTX_SUCCESS/FAILURE
  x libdmtx:   Add edge threshold filtering
  x libdmtx:   Add encoding support for 144x144 barcodes
  x libdmtx:   Fixed encoding case when message starts with two digits
  x libdmtx:   Fixed bug in range limit option
  x libdmtx:   Add dynamic image shrinking (pixel skipping)
  x libdmtx:   Add step-by-step diagnostic image dump (debug build)
  x libdmtx:   Fixed bug in minimum scan gap setting
  x libdmtx:   Removed y-flip from internal pixel storage
  x libdmtx:   Added strict border tests to eliminate false positives
  x libdmtx:   Added squareness deviation filter
  x libdmtx:   Implement simplified Hough transform for locating first edge
  x libdmtx:   Several behind-the-scenes performance enhancements
  x wrapper:   Python wrapper update; 15x faster (thanks Jonathan!)
  x wrapper:   New PHP wrapper code added
  x project:   Various improvements when building for OS X and FreeBSD

version 0.5.1: (01-Jul-2008)
  x libdmtx:   Fixed Extended ASCII encoding bug
  x libdmtx:   Fixed error correction bug related to multiple interleaved blocks
  x libdmtx:   Added timeout condition for region detection
  x libdmtx:   Allow partial and complete disabling of error correction
  x libdmtx:   Replaced DmtxPixel struct with DmtxRgb for safe pixel copies
  x libdmtx:   Tighter integration with libfec
  x dmtxread:  Conditional build logic for libtiff
  x dmtxquery: Start new utility to extra information from dmtxread output
  x testsuite: Started unit test executable for low level testing
  x wrapper:   New Cocoa wrapper for iPhone, iPod Touch, OS X (thanks Stefan!)
  x project:   Include local copies of getopt1.c getopt.c getopt.h
  x project:   Various things to help compiling in MS VC++
  x project:   Added missing header comments

version 0.5: (13-Apr-2008)
  x libdmtx:   Rework encoding and decoding API for consistency and intuitiveness
  x libdmtx:   Handle region detection and region decoding as separate tasks
  x libdmtx:   Pass found regions back to calling app before attempting decode
  x libdmtx:   Image mask approach (for performance and multi-barcode scans)
  x libdmtx:   Remove "2" from functions named *MatrixRegion2*() (whoops)
  x libdmtx:   Fix TestForEndOfSymbolEdifact() to handle special cases correctly
  x libdmtx:   Roll scan pattern into core library (inward breadth-first cross)
  x libdmtx:   Replace dmtxScanLine() with dmtxScanPixel()
  x libdmtx:   Implement 4-direction weighted module decisions (eliminates thresholds)
  x libdmtx:   Error correction using libfec (thanks Florian!)
  x dmtxread:  Add ability to scan portion of image
  x dmtxread:  Add --diagnose option that dumps image with embedded scan infomation
  x dmtxread:  Added Z rotation angle (in degrees) to verbose output
  x dmtxwrite: Move ASCII and codeword output to separate --preview option
  x dmtxwrite: Added -R option for setting image print resolution in dpi (PNG only)
  x project:   Remove gltest and simpletest from default build target
  x project:   Update Subversion to be keyword friendly ($Id$)
  x project:   Updated documentation to reflect API and option changes
  x testsuite: Moved all public images to common directory with single copyright file

version 0.4: (07-Dec-2008)
  x libdmtx:   Remove arbitrary sz scaling (100.0) since it doesn't matter anyway
  x libdmtx:   Fix 4 bottom-right modules in sizes where they are not used (thanks Matthias R.!)
  x libdmtx:   Replace callback references with preprocessor macros
  x libdmtx:   Implement remaining encodation schemes for encoding (X12, Base 256, etc...)
  x libdmtx:   Implement remaining encodation schemes for decoding (X12, Base 256, etc...)
  x libdmtx:   Implement --auto-best option for best possible encoding efficiency
  x libdmtx:   Implement multi-region symbols
  x libdmtx:   Read and write rectangle shaped barcodes
  x libdmtx:   Use GNU autotools (autoconf, automake, libtool)
  x libdmtx:   New region detection overhaul
  x libdmtx:   Fix chcon error in Makefile (right answer might be to use autoconf)
  x bindings:  Include initial version of Python bindings from pydmtx project (thanks Dan!)
  x bindings:  Add decoding functionality through Python
  x bindings:  Expose new encoding functionality through Python
  x dmtxread:  Fix dmtxread crash when same barcode is found more than 16 times
  x dmtxread:  Verbose messages describing traits of detected barcodes
  x dmtxread:  --codewords option to print codewords instead of decoded message
  x dmtxread:  --newline option to insert newline character at end of output
  x dmtxwrite: Additional output formats (PNG, ASCII, codewords)
  x testsuite: 'make test' executes regression tests for encodation
  x testsuite: Add marathon images to project (thanks John!)

version 0.3: (15-Oct-2006)
  x Use preprocessor to pull code into one big file before compiling
  x Update Makefile to handle monolithic approach; add targets for test, util, tarball
  x Rename DmtxInfo struct and variables to DmtxDecode (for consistency with DmtxEncode)
  x Merge placement logic into single implementation for both encoding and decoding
  x Deploy codebase to SourceForge CVS
  x Add revision control keywords to source files
  x Implement remaining encodation schemes in dmtxdecode.c (X12, Base 256, etc...)
  x Create separate file for callback functions (allows them to be optional)
  x Move PNG (and other format) logic and dependencies to dmtxread, dmtxwrite, etc...
  x Fix the regressions (crash bugs) introduced during v0.2 structural rework
  x Add multi-page TIFF capabilities to dmtxread
  x Move pure decode calls from dmtxScanLine into a dmtxdecode.c function
  x Sample module color from more than one pixel location
  x Rename DmtxVector3 to DmtxColor3 and merge into dmtxcolor.c
  x Fix LoadPngImage() in dmtxread.c to return image count
  x Add package/build dependencies to INSTALL file
  x Build coding style test scripts
  x Replace current calibration size estimate with new approach
  x Size step size dynamically according to pixel size
  x Improved dmtxwrite (fixed bugs, implemented -o option)
  x Increase dmtxread default scanline count (feasible because of better stability)
  x Add man page for dmtxwrite

version 0.2: (11-Jun-2006)
  x Move dmtxCapturePixel routine to library code
  x Initial restructuring of code for architectural goodness
  x Improve API for real-world use (and not just dumping results to STDOUT)
  x Add "dmtxread" command line utility
  x Add "dmtxwrite" command line utility
  x Implement error detection
  x Create "simpletest.c" for full-circle processing
  x Use libpng(3) in library to read Data Matrix images
  x Slap together some basic documentation

version 0.1: (22-Apr-2006)
  x Cycle texture images with right-click
  x Complete PlotPoint so it handles floating rows and columns
  x Implement right and left directions of FollowEdge
  x Call right and left edge following scans started from vertical step scans
  x Implement 2D vector and matrix functions
  x Trace lines with actual line object (2D ray)
  x Turn corners when encountering the end of a followed line
  x Build 2d transformation to wrap around region, assuming parallelogram
  x Display pane 4 with reverse-transformed image capture
  x Enhance dmtxCapturePixel to use "area averaging" instead of nearest neighbor
  x Figure out why squares are 3 pixels off (to start: draw white gl lines over follower paths)
  x Add callback function for PlotEventPoint(x, y, event_type)
  x Improve follower logic (weighted line fit)
  x dmtxGetPixel: do averaged interpolation followed by a tMin/tMid/tMax cutoff
  x Add in de-skew transformation
  x Refactor vector libraries to consistently list target parameter first
  x Calibrate based on calibration lines
  x Shrink-fit transformation around region


Future Versions:
-----------------------------------------------------------------
  o libdmtx:   Capture high-level design in documentation (data flow, module analogies)
  o libdmtx:   Try bi-linear approximation (instead of linear) in follower edge detection
  o libdmtx:   Implement fixed point math functions for use on mobile platforms
  o libdmtx:   Add calibration functionality to remove spherical distortion


Perhaps Never:
-----------------------------------------------------------------
  o libdmtx:   Implement pre-ECC200 Data Matrix standards (big effort/low demand)


Website:
-----------------------------------------------------------------
  o Explore using single background image instead of split
  o Add what we currently do, don't do, would like to do in the future
  o Add http://hosted-projects.com/trac/hudora/public/wiki/huBarcode to resources page


Proposed Change: Modularity
-----------------------------------------------------------------
Make finder bar detection pluggable so a separate future version can be
made for dot peen pattern detection (remaining steps would be unchanged).


Proposed Change: Image Scaling
-----------------------------------------------------------------
/**
 * still on the fence whether image scaling factors should be maintained in
 * DmtxDecode ... but right now leaning that way. Thinking goes that any
 * caching will be tied to scale, and scale change should not affect image
 * object. Basically, load the image once and then don't touch it anymore.
 *
 * However, I also want to be able to say:
 *
 *    offset = dmtxImageGetOffset(img, x, y)
 *
 * ... and have the result take scaling into account. This statement really
 * has nothing to do with the decoding process (and therefore decode struct).
 * hmmm ...
 */
typedef struct DmtxDecode_struct {
   int scale;
   int xMin;
   int xMax;
   int yMin;
   int yMax;
   int xMinScaled;
   int xMaxScaled;
   int yMinScaled;
   int yMaxScaled;
} DmtxDecode;


Proposed Change: Region Detection
-----------------------------------------------------------------
The first edge is currently detected using fixed-offset Hough
transform. This is very efficient for the first edge, but forces
all remaining traces to perform additional Hough transforms for
unsuccessful region candidates because we can't say with
certainty: "This previously-tested pixel location does not belong
to a barcode region." This is because it may have been part of a
barcode region but the trail was blazed starting from a non-
finder-bar location so it was ditched when the fixed-offset Hough
transform did not produce a good line.

A better approach might be:

  1) Blaze trail in both directions
  2) Walk entire trail to size the Hough bounding box
  3) Walk entire trail to accumulate Hough lines
     - Can be fast/low-res search since we will tighten later if
       it continues to be a promising candidate
     - Consider overlapping Hough regions to avoid near-border
       confusion and complexity later
  4) Extract 2 best Hough lines (use right angle + convex hull)
  5) Determine region polarity and orientation
  6) etc... (see "Region Calibration" below)

Although more costly for the first detected region, this approach
allows future scans to skip all pixels that have been traversed
previously. This should translate to significant time savings,
especially for noisy and complex images.


Proposed Change: Region Calibration
-----------------------------------------------------------------
The current calibration technique relies solely on points and
angles found during the Hough process, and uses the calibration
bar only to detect symbol size. A more robust approach might take
advantage of the calibration bars' repeating pattern to extract
precise edge locations for the adjacent edges. Doing so will
provide extremely accurate symbol regions since each of the 4
edges will contain a precise anchor point instead of relying on a
potentially fuzzy edge measurement. This will also help with
barcodes created using undersized/oversized printing process.

Continuing from above:

  6) Blaze gapped trail for both calibration bars
     - After this, the basic region shape is known
     - Final trail should be a contiguous trail that is easy to
       follow in either direction, although gapped lines may be
       stored differently as to leave original trail intact
     - Future version might try one at a time for improved
       handling of damaged regions)
  7) Detect symbol size using jump tally approach
  8) Find exact edge locations using Bresenham/Hough approach to
     measure offset and scaling? (super accurate because cosine
     of small angles approaches zero)
  9) Execute final high-res Hough transform on each edge, using
     known points as anchors
     - After this, the precise region shape is known
     - Must use multiple offsets. Best Hough line may not run
       through anchor because we can't assume that our edge-
       finding algorithm necessarily runs along the perfect edge,
       just that it follows the edge consistently. This process
       will simply provide the ideal angle to use.

Step 8 details: While stepping along pixels on Bresenham line we
always know whether we are sitting on the primary or secondary
color. The Hough transform will store a 2D array of bracketed
scalings and offsets, which we will increment if our actual color
matches the predicted array element color. After traversing the
line once, we will know the exact scaling and offset.

This approach uses a fast-and-rough fit followed by a high
precision fit. While it would be convenient if we could capture
everything in one pass, this approach offers some significant
advantages:

  * Regions that turn out to be bad are filtered out early in the
    process before spending much time on them
  * Fast-and-rough fit requires less memory
  * Allows for simpler logic; Not trying to do too much at once
  * Programs that do their own rough region detection can still
    use libdmtx high precision fit
  * High precision fit should apply equally well to contiguous-
    edge and dot peen symbols


Proposed Change: Latest thoughts on region detection
-----------------------------------------------------------------

* Allocate memory cache, one byte per pixel

  bits: cuuutddd
        --------
        12345678

  c = connected edge flag
  u = upstream direction
  t = meets min threshold flag
  d = downstream direction

* Step through entire image and assign best downstream neighbor if above certain
  threshold. (sets t and d bits)

* Step through grid locations looking for edge candidates:

* If below threshold (t == 0) OR
  if edge was connected in a previous step (c == 1)
  then skip to next

* Follow the edge upstream and downstream, leaving connected trails both upstream
  and downstream. This should follow the existing downstream directions, but may
  involve assigning new downstream directions to unpopulated locations in order
  to bridge any small gaps. At each location, mark c = 1 and u = upstream direction.
  If necessary, u == d can indicate special case (trail end?) since this can't
  occur naturally otherwise.

* If connected trail is short then skip to next

* Step along connected trail and form bounding box limits

* If bounding box is small then skip to next

* Step along connected trail to measure finder bars using Hough Transform

* If Hough lines look stupid then skip to next

* Align/Transform region based on finder bars

* Run Boundary Hough on entire interior "L" region. Use Hough orientation based
  on direction being scanned. For example, when looking for horizontal vanishing
  point, optimize for horizontal lines, and take into account the region polarity.
  This might make it clean enough for dot peen detection using the same approach.

* Extract horizontal and vertical vanishing points

* Align/Transform region based on vanishing points

* Find limits in orthagonal region

-----------------------------------------------------------------

Implementation strategy:

1) Confirm that "L" extraction works using Ordinary Hough
   - Use Ordinary Hough because edge is not jagged and interior is unknown

2) Change trunk to use above cache storage layout, but not changing
   approach yet. Also move cache to DmtxDecode. Prepopulate downstream
   neighbors?

3) Change trunk to use "L" extraction above
   - emphasis on angle instead of offset
   - overlap offsets to avoid split condition
   - use convex hull
   - use right angles
   - determine polarity

4) Implement fast multi-scanning (skip previously-visited locs)

Release 0.7

5) Confirm that Boundary Hough concept works
   - test on all conditions
   - Boundary Hough needs to use color polarity
   - Boundary Hough needs to use interior direction

6) Confirm that vanishping point detection works
   - use Boundary Hough
   - test for vanishing points
   - test for dot peen

7) Change trunk to detect vanishing point with Boundary Hough
   - can pattern also be detected with this approach?

8) Align/transform based on vanishing point

9) Detect solid black and solid white bars

10) Tight fit based on repeating calibration pattern


For Release 0.8
-----------------------------------------------------------------

  byte 1:  pntflow
          --------
             0-255

  byte 2: xcuuuddd
          --------
          12345678

  c = connected edge flag
  u = upstream direction
  d = downstream direction

Ordinary Hough test:

for each color channel:
   allocate image and image cache (2 bytes per pixel)
   assign point flow for each pixel (byte 1), and 3 bits for direction

   offset = y * img->width + x;
   colorPattern[0] = img->pxl[(offset - img->width - 1) * 3];
   colorPattern[1] = img->pxl[(offset - img->width    ) * 3];
   colorPattern[2] = img->pxl[(offset - img->width + 1) * 3];
   colorPattern[3] = img->pxl[(offset              + 1) * 3];
   colorPattern[4] = img->pxl[(offset + img->width + 1) * 3];
   colorPattern[5] = img->pxl[(offset + img->width    ) * 3];
   colorPattern[6] = img->pxl[(offset + img->width - 1) * 3];
   colorPattern[7] = img->pxl[(offset              - 1) * 3];

   write out pnm dump 1
   connect edges downstream, leaving trail

   - pick starting loc where downstream points back (how to measure this?)

*** in a river, you know you are in the center of the stream when your ***
*** neighbor on each side is moving slower than you                    ***

   - follow outward, leave upstream trail
   - pick next loc by choosing strongest of 5 neighbors that do not reverse
     course
   - follow outward, leave upstream trail
   - repeat
   connect edges upstream, leaving trail
   - do reverse of above
   - store the final upstream jump, to be used as starting point for walks
   write out pnm dump 2
   step along trail to build bounding box
   step along trail to accumulate Hough sums
   write out pnm dump 3 representing Hough sums
   write out pnm dump 4 with Bresenham lines drawn along all winning edges

-----------------------------------------------------------------

Boundary Hough test:

increment line
decrement interior line

-----------------------------------------------------------------

Vanishing Point detection:

Known:
  "L" alignment edge location

Approach:
  1) Sample each pixel in a parallelogram formed by the "L" edges
     and implied opposing parallel edges
  2) Sample each pixel within region exactly once
  3) Perform Boundary Hough test twice, once for each edge of "L"
     to define interior direction
  4) Detect interior edges as pattern of points in Hough grid
  5) 2 skew tranforms should be sufficient to correct any
     perspective distortion
  6) Find calibration edges and extract exact edge locations

Note: Initial implementation may use regular Hough if much simpler
