r19687 by jghali - #12858: Barcode plugin updated barcode.ps file + some necessary changes

scribus-commit scribus-commit at lists.scribus.net
Sat Dec 27 01:57:27 UTC 2014


Author: jghali
Date: Sat Dec 27 01:57:27 2014
New Revision: 19687

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=19687
Log:
#12858: Barcode plugin updated barcode.ps file + some necessary changes

Modified:
    branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.cpp
    branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.ps
    branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcodegenerator.cpp

Modified: branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19687&path=/branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.cpp (original)
+++ branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.cpp Sat Dec 27 01:57:27 2014
@@ -38,9 +38,9 @@
 	about->authors = QString::fromUtf8("Terry Burton - <tez at terryburton.co.uk>, Petr Van\xc4\x9bk <petr at scribus.info>");
 	about->shortDescription = tr("Scribus frontend for Pure PostScript Barcode Writer");
 	about->description = "Barcode Writer in Pure PostScript is an award-winning open source barcode maker, as used by NASA, that facilitates the printing of all major barcode symbologies entirely within level 2 PostScript, ideal for variable data printing. The complete process of generating printed barcodes is performed entirely within the printer (or print system) so that it is no longer the responsibility of your application or a library. There is no need for any barcode fonts and the flexibility offered by direct PostScript means you can avoid re-implementing barcode generator code, or migrating to new libraries, whenever your project language needs change.\nhttp://www.terryburton.co.uk/barcodewriter/";
-	about->version = "Backend: 2013-02-27";
+	about->version = "Backend: 2014-12-11";
 	// about->releaseDate
-	about->copyright = QString::fromUtf8("Backend: Copyright (c) 2004-2013 Terry Burton - tez at terryburton.co.uk\nFrontend: Copyright (c) 2005 Petr Van\xc4\x9bk - petr at scribus.info");
+	about->copyright = QString::fromUtf8("Backend: Copyright (c) 2004-2014 Terry Burton - tez at terryburton.co.uk\nFrontend: Copyright (c) 2005 Petr Van\xc4\x9bk - petr at scribus.info");
 	about->license = "Backend: MIT/X-Consortium, Frontend: GPL";
 	return about;
 }

Modified: branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.ps
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19687&path=/branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.ps
==============================================================================
--- branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.ps (original)
+++ branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcode.ps Sat Dec 27 01:57:27 2014
@@ -1,14 +1,9 @@
-%!PS-Adobe-2.0
-%%Creator: Terry Burton
-%%DocumentPaperSizes: a4
-%%EndComments
-
-% Barcode Writer in Pure PostScript - Version 2013-02-27
-% http://www.terryburton.co.uk/barcodewriter/
+%!PS
+
+% Barcode Writer in Pure PostScript - Version 2014-12-11
+% http://bwipp.terryburton.co.uk
 %
-% Copyright (c) 2004-2013 Terry Burton
-%
-% $Id$
+% Copyright (c) 2004-2014 Terry Burton
 %
 % Permission is hereby granted, free of charge, to any
 % person obtaining a copy of this software and associated
@@ -34,28 +29,49 @@
 % CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 % IN THE SOFTWARE.
 
-% Uncomment this next line to allow these named resource
-% definitions to remain resident within a printer's
-% PostScript virtual machine so that the barcode generation
-% capability persists between jobs.
-
-% serverdict begin 0 exitserver 
-
 % --BEGIN TEMPLATE--
 
-% --BEGIN PREAMBLE--
+% --BEGIN RESOURCE preamble--
+%%BeginResource: Category uk.co.terryburton.bwipp 0.0 2014121100 35431 31768
+%%BeginData:          6 ASCII Lines
 currentglobal
 true setglobal
-/Generic /Category findresource
-dup length 1 add dict copy
-dup /InstanceType /packedarraytype put
+/Generic /Category findresource dup length 1 add dict copy dup
+/InstanceType /setpacking where {pop /packedarraytype} {/arraytype} ifelse put
 /uk.co.terryburton.bwipp exch /Category defineresource pop
 setglobal
-% --END PREAMBLE--
-
-% --BEGIN RENDERER renlinear--
+%%EndData
+%%EndResource
+% --END RESOURCE preamble--
+
+% --BEGIN RESOURCE raiseerror--
+% --REQUIRES preamble--
+%%BeginResource: uk.co.terryburton.bwipp raiseerror 0.0 2014121100 112145 43907
+%%BeginData:         13 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+begin
+/raiseerror {
+  $error exch /errorinfo exch put
+  $error exch /errorname exch put
+  $error /command null put
+  $error /newerror true put 
+  handleerror quit
+} bind def
+/raiseerror dup load /uk.co.terryburton.bwipp defineresource pop
+end
+/setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
+% --END RESOURCE raiseerror--
+
+% --BEGIN RENDERER renlinear--
+% --REQUIRES preamble raiseerror--
+%%BeginResource: uk.co.terryburton.bwipp renlinear 0.0 2014121100 80415 79633
+%%BeginData:        237 ASCII Lines
+/setpacking where {pop currentpacking true setpacking} if
+1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 begin
 /renlinear {
 
@@ -290,11 +306,17 @@
 /renlinear dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END RENDERER renlinear--
 
 % --BEGIN RENDERER renmatrix--
+% --REQUIRES preamble raiseerror--
+%%BeginResource: uk.co.terryburton.bwipp renmatrix 0.0 2014121100 54629 54335
+%%BeginData:         66 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 begin
 /renmatrix {
 
@@ -335,21 +357,21 @@
     0 0 moveto pixx 0 lineto pixx pixy lineto 0 pixy lineto closepath
     backgroundcolor (unset) ne { gsave backgroundcolor setanycolor fill grestore } if 
     barcolor (unset) ne { barcolor setanycolor } if
-    /i 0 def
-    pixs {
-	/x i pixx mod def
-	/y pixy 1 sub i pixx idiv sub def
-	1 eq {
-	    newpath
-	    x y moveto
-	    1 0 rlineto
-	    0 1 rlineto
-	    -1 0 rlineto
-	    0 -1 rlineto
-	    closepath fill
-	} if
-	/i i 1 add def
-    } forall
+    /xyget {pixx mul add get} bind def
+    newpath
+    0 1 pixs length 1 sub {
+        dup pixx mod /x exch def
+        pixx idiv /y exch def
+        pixs x y xyget 1 eq {
+           x pixy y sub 1 sub moveto
+           0 1 rlineto
+           1 0 rlineto
+           0 -1 rlineto
+           -1 0 rlineto
+           closepath
+        } if
+    } for
+    fill
     grestore
 
     end
@@ -358,29 +380,59 @@
 /renmatrix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END RENDERER renmatrix--
 
 % --BEGIN RENDERER renmaximatrix--
+% --REQUIRES preamble raiseerror--
+%%BeginResource: uk.co.terryburton.bwipp renmaximatrix 0.0 2014121100 55829 55803
+%%BeginData:         79 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 begin
 /renmaximatrix {
 
     20 dict begin
 
     /args exch def   % We are given some arguments
+
+    % Default options
+    /barcolor (unset) def
+    /backgroundcolor (unset) def
 
     % Apply the renderer options and the user options
     args {def} forall
     opt {def} forall
- 
+
+    /barcolor barcolor cvlit def
+    /backgroundcolor backgroundcolor cvlit def
+
+    % Set RGB or CMYK color depending on length of given hex string
+    /setanycolor {
+        /anycolor exch def
+        anycolor length 6 eq {
+            (<      >) 8 string copy dup 1 anycolor putinterval cvx exec {255 div} forall setrgbcolor
+        } if
+        anycolor length 8 eq {
+            (<        >) 10 string copy dup 1 anycolor putinterval cvx exec {255 div} forall setcmykcolor
+        } if
+    } bind def
+
     gsave
 
     currentpoint translate
 
     2.4945 dup scale  % from 1pt to 1.88mm
+
+    0 0 moveto 30 0 lineto 30 29 lineto 0 29 lineto closepath
+    backgroundcolor (unset) ne { gsave backgroundcolor setanycolor fill grestore } if 
+    barcolor (unset) ne { barcolor setanycolor } if
+
     0.5 0.5774 translate
 
+    newpath
     pixs {
         dup 
         /x exch 30 mod def 
@@ -395,8 +447,9 @@
         0.5   0.2887 rlineto
         0     0.5774 rlineto
         -0.5  0.2887 rlineto
-        closepath fill
+        closepath
     } forall
+    fill
 
     % Plot the locator symbol
     newpath 14 13.8576 0.5774 0 360 arc closepath
@@ -414,15 +467,21 @@
 /renmaximatrix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END RENDERER renmaximatrix--
 
 % --BEGIN ENCODER ean5--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: EAN-5 (5 digit addon)
 % --EXAM: 90200
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ean5 0.0 2014121100 64068 63875
+%%BeginData:        135 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /ean5 {
@@ -460,7 +519,17 @@
     } {
         /textyoffset textyoffset cvr def
     } ifelse
-    
+
+    % Validate input
+    barcode length 5 ne {
+        /bwipp.ean5badLength (EAN-5 add-on must be 5 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.ean5badCharacter (EAN-5 add-on must contain only digits) //raiseerror exec
+        } if
+    } forall
+ 
     % Create an array containing the character mappings
     /encs
     [ (3211) (2221) (2122) (1411) (1132)
@@ -545,15 +614,21 @@
 /ean5 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean5--
 
 % --BEGIN ENCODER ean2--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: EAN-2 (2 digit addon)
 % --EXAM: 05
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ean2 0.0 2014121100 62753 62505
+%%BeginData:        120 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /ean2 {
@@ -591,6 +666,16 @@
     } {
         /textyoffset textyoffset cvr def
     } ifelse
+
+    % Validate input
+    barcode length 2 ne {
+      /bwipp.ean2badLength (EAN-2 add-on must be 2 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.ean2badCharacter (EAN-2 add-on must contain only digits) //raiseerror exec
+        } if
+    } forall
     
     % Create an array containing the character mappings
     /encs
@@ -661,16 +746,21 @@
 /ean2 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean2--
 
 % --BEGIN ENCODER ean13--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2--
 % --DESC: EAN-13
-% --EXAM: 2071473968010
+% --EXAM: 2112345678900
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ean13 0.0 2014121100 87471 83758
+%%BeginData:        215 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean2 dup /uk.co.terryburton.bwipp findresource put
 dup /ean5 dup /uk.co.terryburton.bwipp findresource put
@@ -726,7 +816,20 @@
         pop
         /addon () def
     } ifelse
- 
+
+    % Validate the input
+    barcode length 12 ne barcode length 13 ne and {
+        /bwipp.ean13badLength (EAN-13 must be 12 or 13 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.ean13badCharacter (EAN-13 must contain only digits) //raiseerror exec
+        } if
+    } forall
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.ean13badAddOnLength (Add-on for EAN-13 must be 2 or 5 digits) //raiseerror exec
+    } if
+
     % Add checksum digit
     /pad 13 string def
     /checksum 0 def
@@ -740,6 +843,11 @@
         } ifelse
     } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 13 eq {
+        barcode 12 get checksum 48 add ne {
+            /bwipp.ean13badCheckDigit (Incorrect EAN-13 check digit provided) //raiseerror exec
+        } if
+    } if
     pad 0 barcode putinterval       % Add barcode to the start of the pad
     pad 12 checksum 48 add put      % Put ascii for checksum at end of pad
     /barcode pad def
@@ -865,16 +973,21 @@
 /ean13 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean13--
 
 % --BEGIN ENCODER ean8--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2--
 % --DESC: EAN-8
-% --EXAM: 01335583
-% --EXOP: includetext guardwhitespace height=0.5
+% --EXAM: 02345673
+% --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ean8 0.0 2014121100 84693 80881
+%%BeginData:        196 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean2 dup /uk.co.terryburton.bwipp findresource put
 dup /ean5 dup /uk.co.terryburton.bwipp findresource put
@@ -931,6 +1044,19 @@
         /addon () def
     } ifelse
 
+    % Validate the input
+    barcode length 7 ne barcode length 8 ne and {
+        /bwipp.ean8badLength (EAN-8 must be 7 or 8 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.ean8badCharacter (EAN-8 must contain only digits) //raiseerror exec
+        } if
+    } forall
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.ean8badAddOnLength (Add-on for EAN-8 must be 2 or 5 digits) //raiseerror exec
+    } if
+
     % Add checksum digit
     /pad 8 string def
     /checksum 0 def
@@ -944,6 +1070,11 @@
         } ifelse
     } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 8 eq {
+        barcode 7 get checksum 48 add ne {
+            /bwipp.ean8badCheckDigit (Incorrect EAN-8 check digit provided) //raiseerror exec
+        } if
+    } if
     pad 0 barcode putinterval      % Add barcode to the start of the pad
     pad 7 checksum 48 add put      % Put ascii for checksum at end of pad
     /barcode pad def
@@ -1050,16 +1181,21 @@
 /ean8 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean8--
 
 % --BEGIN ENCODER upca--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2--
 % --DESC: UPC-A
-% --EXAM: 488581014973
+% --EXAM: 416000336108
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp upca 0.0 2014121100 92328 88533
+%%BeginData:        248 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean2 dup /uk.co.terryburton.bwipp findresource put
 dup /ean5 dup /uk.co.terryburton.bwipp findresource put
@@ -1115,6 +1251,64 @@
         pop
         /addon () def
     } ifelse
+
+    % Expand a given UPC-E
+    barcode length 7 eq barcode length 8 eq or {
+        % Validate the input
+        barcode {
+            dup 48 lt exch 57 gt or {
+                /bwipp.upcAupcEbadCharacter (UPC-E must contain only digits) //raiseerror exec
+            } if
+        } forall
+        barcode 0 get dup 48 ne exch 49 ne and {
+            /bwipp.upcAupcEbadNumberSystem (UPC-E must have number system 0 or 1) //raiseerror exec
+        } if
+        1 {  % Common exit
+            /upcacode barcode length 8 eq {12} {11} ifelse string def
+            barcode 6 get 48 sub 2 le {
+                upcacode 0 barcode 0 3 getinterval putinterval
+                upcacode 3 barcode 6 1 getinterval putinterval
+                upcacode 4 (0000) putinterval
+                upcacode 8 barcode 3 3 getinterval putinterval
+                exit
+            } if
+            barcode 6 get 48 sub 3 eq {
+                upcacode 0 barcode 0 4 getinterval putinterval
+                upcacode 4 (00000) putinterval
+                upcacode 9 barcode 4 2 getinterval putinterval
+                exit
+            } if
+            barcode 6 get 48 sub 4 eq {
+                upcacode 0 barcode 0 5 getinterval putinterval
+                upcacode 5 (00000) putinterval
+                upcacode 10 barcode 5 1 getinterval putinterval
+                exit
+            } if
+            barcode 6 get 48 sub 5 ge {
+                upcacode 0 barcode 0 6 getinterval putinterval
+                upcacode 6 (0000) putinterval
+                upcacode 10 barcode 6 1 getinterval putinterval
+                exit
+            } if
+        } repeat
+        barcode length 8 eq {
+            upcacode 11 barcode 7 1 getinterval putinterval
+        } if
+        /barcode upcacode def
+    } if
+
+    % Validate the input
+    barcode length 11 ne barcode length 12 ne and {
+        /bwipp.upcAbadLength (UPC-A must be 11 or 12 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.upcAbadCharacter (UPC-A must contain only digits) //raiseerror exec
+        } if
+    } forall
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.upcAbadAddOnLength (Add-on for UPC-A must be 2 or 5 digits) //raiseerror exec
+    } if
  
     % Add checksum digit to barcode
     /pad 12 string def   % Create pad one bigger than barcode
@@ -1129,6 +1323,11 @@
         } ifelse
     } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 12 eq {
+        barcode 11 get checksum 48 add ne {
+            /bwipp.upcAbadCheckDigit (Incorrect UPC check digit provided) //raiseerror exec
+        } if
+    } if
     pad 0 barcode putinterval       % Add barcode to the start of the pad
     pad 11 checksum 48 add put      % Put ascii for checksum at end of pad
     /barcode pad def
@@ -1242,16 +1441,21 @@
 /upca dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER upca--
 
 % --BEGIN ENCODER upce--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2--
 % --DESC: UPC-E
 % --EXAM: 00123457
-% --EXOP: includetext height=0.4
+% --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp upce 0.0 2014121100 97037 93389
+%%BeginData:        287 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean2 dup /uk.co.terryburton.bwipp findresource put
 dup /ean5 dup /uk.co.terryburton.bwipp findresource put
@@ -1298,11 +1502,6 @@
     addontextxoffset (unset) ne {/addontextxoffset addontextxoffset cvr def} if
     addontextyoffset (unset) ne {/addontextyoffset addontextyoffset cvr def} if
 
-    % Ensure 0 or 1 number systems
-    barcode 0 get dup 48 ne exch 49 ne and {
-        /barcode () def
-    } if
-
     % Split off the addon
     barcode ( ) search {
         /barcode exch def
@@ -1313,6 +1512,65 @@
         /addon () def
     } ifelse
 
+    % Compress a given UPC-A
+    barcode length 11 eq barcode length 12 eq or {
+        % Validate the input
+        barcode {
+            dup 48 lt exch 57 gt or {
+                /bwipp.upcEupcAbadCharacter (UPC-A must contain only digits) //raiseerror exec
+            } if
+        } forall
+        1 {  % Common exit
+            /upcecode barcode length 12 eq {8} {7} ifelse string def
+            barcode 3 get 48 sub 2 le barcode 4 4 getinterval (0000) eq and {
+                upcecode 0 barcode  0 3 getinterval putinterval
+                upcecode 3 barcode  8 3 getinterval putinterval
+                upcecode 6 barcode  3 1 getinterval putinterval
+                exit
+            } if
+            barcode 4 5 getinterval (00000) eq {
+                upcecode 0 barcode  0 4 getinterval putinterval
+                upcecode 4 barcode  9 2 getinterval putinterval
+                upcecode 6 (3) putinterval
+                exit
+            } if
+            barcode 5 5 getinterval (00000) eq {
+                upcecode 0 barcode  0 5 getinterval putinterval
+                upcecode 5 barcode 10 1 getinterval putinterval
+                upcecode 6 (4) putinterval
+                exit
+            } if
+            barcode 10 get 48 sub 5 ge barcode 6 4 getinterval (0000) eq and {
+                upcecode 0 barcode  0 6 getinterval putinterval
+                upcecode 6 barcode 10 1 getinterval putinterval
+                exit
+            } if
+            /bwipp.upcEupcAnotCompressible (UPC-A cannot be converted to a UPC-E) //raiseerror exec
+        } repeat
+        barcode length 12 eq {
+            upcecode 7 barcode 11 1 getinterval putinterval
+        } if
+        /barcode upcecode def
+    } if
+
+    % Validate the input
+    barcode length 7 ne barcode length 8 ne and {
+        /bwipp.upcEbadLength (UPC-E must be 7 or 8 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.upcEbadCharacter (UPC-E must contain only digits) //raiseerror exec
+        } if
+    } forall
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.upcEbadAddOnLength (Add-on for UPC-E must be 2 or 5 digits) //raiseerror exec
+    } if
+
+    % Ensure 0 or 1 number systems
+    barcode 0 get dup 48 ne exch 49 ne and {
+        /bwipp.upcEbadNumberSystem (UPC-E must have number system 0 or 1) //raiseerror exec
+    } if
+
     % Create an array containing the character mappings
     /encs
     [ (3211) (2221) (2122) (1411) (1132)
@@ -1329,25 +1587,34 @@
     ] def
 
     % Derive the equivalent UPC-A for its checksum
-    /upcacode (00000000000) 11 string copy def
-    upcacode 0 barcode 0 get put
-    barcode 6 get 48 sub 2 le {
-        upcacode 1 barcode 1 2 getinterval putinterval
-        upcacode 3 barcode 6 1 getinterval putinterval
-        upcacode 8 barcode 3 3 getinterval putinterval
-    } if
-    barcode 6 get 48 sub 3 eq {
-        upcacode 1 barcode 1 3 getinterval putinterval
-        upcacode 9 barcode 4 2 getinterval putinterval
-    } if
-    barcode 6 get 48 sub 4 eq {
-        upcacode 1 barcode 1 4 getinterval putinterval
-        upcacode 10 barcode 5 1 getinterval putinterval
-    } if
-    barcode 6 get 48 sub 5 ge {
-        upcacode 1 barcode 1 5 getinterval putinterval
-        upcacode 10 barcode 6 1 getinterval putinterval
-    } if
+    1 {  % Common exit
+        /upcacode 11 string def
+        barcode 6 get 48 sub 2 le {
+            upcacode 0 barcode 0 3 getinterval putinterval
+            upcacode 3 barcode 6 1 getinterval putinterval
+            upcacode 4 (0000) putinterval
+            upcacode 8 barcode 3 3 getinterval putinterval
+            exit
+        } if
+        barcode 6 get 48 sub 3 eq {
+            upcacode 0 barcode 0 4 getinterval putinterval
+            upcacode 4 (00000) putinterval
+            upcacode 9 barcode 4 2 getinterval putinterval
+            exit
+        } if
+        barcode 6 get 48 sub 4 eq {
+            upcacode 0 barcode 0 5 getinterval putinterval
+            upcacode 5 (00000) putinterval
+            upcacode 10 barcode 5 1 getinterval putinterval
+            exit
+        } if
+        barcode 6 get 48 sub 5 ge {
+            upcacode 0 barcode 0 6 getinterval putinterval
+            upcacode 6 (0000) putinterval
+            upcacode 10 barcode 6 1 getinterval putinterval
+            exit
+        } if
+    } repeat
     /checksum 0 def
     0 1 10 {
        /i exch def
@@ -1359,6 +1626,11 @@
        } ifelse
     } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 8 eq {
+        barcode 7 get checksum 48 add ne {
+            /bwipp.upcEbadCheckDigit (Incorrect UPC check digit provided) //raiseerror exec
+        } if
+    } if
     /pad 8 string def
     pad 0 barcode putinterval       % Add barcode to the start of the pad
     pad 7 checksum 48 add put       % Put ascii for checksum at end of pad
@@ -1468,17 +1740,21 @@
 /upce dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER upce--
 
 % --BEGIN ENCODER isbn--
-% --REQUIRES ean13--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2 ean13--
 % --DESC: ISBN
-% --EXAM: 978-1-56592-479 54495
+% --EXAM: 978-1-56581-231-4 52250
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp isbn 0.0 2014121100 92829 99144
+%%BeginData:        252 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean13 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -1487,7 +1763,7 @@
     20 dict begin
 
     /options exch def      % We are given an options string
-    /isbntxt exch def      % We are given the isbn text with dashes
+    /barcode exch def      % We are given the isbn text with dashes
 
     /dontdraw false def
     /includetext false def  % Enable/disable ISBN text
@@ -1518,68 +1794,161 @@
     /addongap addongap cvr def
 
     % Split off the addon
-    isbntxt ( ) search {
-        /isbntxt exch def
+    barcode ( ) search {
+        /barcode exch def
         pop
         /addon exch def
     } {
         pop
         /addon () def
     } ifelse
- 
-    % Convert ISBN-10 to ISBN-13
-    legacy not isbntxt length 13 le and {
-        /pad isbntxt length 4 add string def
-        pad 0 (978-) putinterval
-        pad 4 isbntxt putinterval
-        /isbntxt pad def
-    } if
-
-    % Read the digits from isbntxt and calculate checksums
-    /isbn 13 string def
-    /checksum10 0 def
-    /checksum13 0 def
-    /i 0 def /n 0 def
-    { % loop
-        /isbnchar isbntxt i get 48 sub def
-        isbnchar -3 ne {     % Ignore dashes
-            isbn n isbnchar 48 add put
-            n 9 lt {
-                /checksum10 checksum10 10 n sub isbnchar mul add def
+
+    % Validate the input
+    barcode length 15 ne barcode length 17 ne and
+    barcode length 11 ne barcode length 13 ne and and {
+        /bwipp.isbnBadLength (ISBN-13 must be 15 or 17 characters including dashes. ISBN-10 must be 11 or 13 characters including dashes) //raiseerror exec
+    } if
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.isbnBadAddOnLength (Add-on for ISBN must be 2 or 5 digits) //raiseerror exec
+    } if
+    barcode length 15 ge {  % ISBN-13
+        barcode 0 4 getinterval dup (978-) ne exch (979-) ne and {
+            /bwipp.isbn13badPrefix (ISBN-13 prefix must be 978- or 979-) //raiseerror exec
+        } if
+        /wasdash false def /numdash 0 def /numdigit 0 def
+        barcode 5 9 getinterval {
+            dup
+            45 eq {
+                wasdash {
+                    /bwipp.isbn13adjacentDashes (ISBN-13 does not permit adjacent dashes) //raiseerror exec
+                } if
+                /wasdash true def
+                /numdash numdash 1 add def
             } if
-            n 12 lt {
-                n 2 mod 0 eq {
-                    /checksum13 isbnchar checksum13 add def
-                } {
-                    /checksum13 isbnchar 3 mul checksum13 add def
-                } ifelse
+            dup 48 ge exch 57 le and {
+                /wasdash false def
+                /numdigit numdigit 1 add def
             } if
-            /n n 1 add def
-        } if
-        /i i 1 add def
-        i isbntxt length eq {exit} if
-    } loop
+        } forall
+        numdash 2 ne numdigit 7 ne or {
+            /bwipp.isbn13numDashesDigits (Incorrect number of dashes and digits for ISBN-13) //raiseerror exec
+        } if
+        barcode 14 get dup 48 lt exch 57 gt or {
+            /bwipp.isbn13character15 (ISBN-13 character 15 must be a digit) //raiseerror exec
+        } if
+        barcode length 17 eq {
+            barcode 15 1 getinterval (-) ne {
+                /bwipp.isbn13character16 (ISBN-13 penultimate character must be a dash) //raiseerror exec
+            } if
+            barcode 16 get dup 48 lt exch 57 gt or {
+                /bwipp.isbn13character17 (ISBN-13 final character must be a digit) //raiseerror exec
+            } if
+        } if
+    } {  % ISBN-10
+        barcode 0 get dup 48 lt exch 57 gt or {
+            /bwipp.isbn10FirstDigit (ISBN-10 first character must be a digit) //raiseerror exec
+        } if
+        /wasdash false def /numdash 0 def /numdigit 0 def
+        barcode 1 9 getinterval {
+            dup
+            45 eq {
+                wasdash {
+                    /bwipp.isbn10adjacentDashes (ISBN-10 does not permit adjacent dashes) //raiseerror exec
+                } if
+                /wasdash true def
+                /numdash numdash 1 add def
+            } if
+            dup 48 ge exch 57 le and {
+                /wasdash false def
+                /numdigit numdigit 1 add def
+            } if
+        } forall
+        numdash 2 ne numdigit 7 ne or {
+            /bwipp.isbn10numDashesDigits (Incorrect number of dashes and digits for ISBN-10) //raiseerror exec
+        } if
+        barcode 10 get dup 48 lt exch 57 gt or {
+            /bwipp.isbn10character11 (ISBN-10 character 11 must be a digit) //raiseerror exec
+        } if
+        barcode length 13 eq {
+            barcode 11 1 getinterval (-) ne {
+                /bwipp.isbn10character12 (ISBN-10 penultimate character must be a dash) //raiseerror exec
+            } if
+            barcode 12 get dup dup 48 lt exch 57 gt or exch 88 ne and {
+                /bwipp.isbn10character13 (ISBN-10 final character must be a digit or X) //raiseerror exec
+            } if
+        } if
+    } ifelse
+
+    /isbntxt barcode def
+
+    % Read the digits from isbntxt and validate checksum for ISBN-10
+    isbntxt length 13 le {
+        /isbn 10 string def
+        /checksum 0 def
+        /i 0 def /n 0 def
+        { % loop
+            /isbnchar isbntxt i get 48 sub def
+            isbnchar -3 ne {     % Ignore dashes
+                isbn n isbnchar 48 add put
+                n 9 lt {
+                    /checksum checksum 10 n sub isbnchar mul add def
+                } if
+                /n n 1 add def
+            } if
+            /i i 1 add def
+            i isbntxt length eq {exit} if
+        } loop
+        /checksum 11 checksum 11 mod sub 11 mod dup 10 eq {pop 40} if 48 add def
+        /isbn isbn 0 9 getinterval def
+        isbntxt length 13 eq {
+            isbntxt 12 get checksum ne {
+                /bwipp.isbn10badCheckDigit (Incorrect ISBN-10 check digit provided) //raiseerror exec
+            } if
+        } if
+    } if
+
+    legacy not isbntxt length 15 ge or {
+
+        % Convert ISBN-10 to ISBN-13
+        isbntxt length 13 le {
+            /pad 15 string def
+            pad 0 (978-) putinterval
+            pad 4 isbntxt 0 11 getinterval putinterval
+            /isbntxt pad def
+        } if
+
+        % Read the digits from isbntxt and validate checksum for ISBN-13
+        /isbn 13 string def
+        /checksum 0 def
+        /i 0 def /n 0 def
+        { % loop
+            /isbnchar isbntxt i get 48 sub def
+            isbnchar -3 ne {     % Ignore dashes
+                isbn n isbnchar 48 add put
+                n 12 lt {
+                    /checksum isbnchar n 2 mod 0 ne {3 mul} if checksum add def
+                } if
+                /n n 1 add def
+            } if
+            /i i 1 add def
+            i isbntxt length eq {exit} if
+        } loop
+        /checksum 10 checksum 10 mod sub 10 mod 48 add def
+        /isbn isbn 0 12 getinterval def
+        isbntxt length 17 eq {
+            isbntxt 16 get checksum ne {
+                /bwipp.isbn13badCheckDigit (Incorrect ISBN-13 check digit provided) //raiseerror exec
+            } if
+        } if
+
+    } if
 
     % Add the ISBN header to the isbntxt
-    n 9 eq n 10 eq or {
-        /checksum 11 checksum10 11 mod sub 11 mod def
-        /isbn isbn 0 9 getinterval def
-        /pad 18 string def
-    } {
-        /checksum 10 checksum13 10 mod sub 10 mod def
-        /isbn isbn 0 12 getinterval def
-        /pad 22 string def
-    } ifelse
+    /pad isbn length 12 eq {22} {18} ifelse string def
     pad 0 (ISBN ) putinterval
-    pad 5 isbntxt putinterval  % Add isbntxt to the pad
-
-    % Add checksum digit
-    pad pad length 2 sub 45 put  % Put a dash
-    checksum 10 eq {
-        pad pad length 1 sub checksum 78 add put  % Check digit for 10 is X
-    } {
-        pad pad length 1 sub checksum 48 add put  % Put check digit
-    } ifelse
+    pad 5 isbntxt putinterval
+    pad pad length 2 sub 45 put
+    pad pad length 1 sub checksum put
     /isbntxt pad def
 
     % Convert ISBN digits to EAN-13
@@ -1635,17 +2004,21 @@
 /isbn dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER isbn--
 
 % --BEGIN ENCODER ismn--
-% --REQUIRES ean13--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear ean5 ean2 ean13--
 % --DESC: ISMN
-% --EXAM: 979-0-2600-0043
+% --EXAM: 979-0-2605-3211-3
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ismn 0.0 2014121100 89401 95601
+%%BeginData:        231 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean13 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -1654,7 +2027,7 @@
     20 dict begin
 
     /options exch def      % We are given an options string
-    /ismntxt exch def      % We are given the ismn text with dashes
+    /barcode exch def      % We are given the ismn text with dashes
 
     /dontdraw false def
     /includetext false def  % Enable/disable ISMN text
@@ -1685,8 +2058,8 @@
     /addongap addongap cvr def
    
     % Split off the addon
-    ismntxt ( ) search {
-        /ismntxt exch def
+    barcode ( ) search {
+        /barcode exch def
         pop
         /addon exch def
     } {
@@ -1694,9 +2067,90 @@
         /addon () def
     } ifelse
 
+    % Validate the input
+    barcode length 15 ne barcode length 17 ne and
+    barcode length 11 ne barcode length 13 ne and and {
+        /bwipp.ismnBadLength (ISMN-13 must be 15 or 17 characters including dashes. ISMN-10 must be 11 or 13 characters including dashes) //raiseerror exec
+    } if
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.ismnBadAddOnLength (Add-on for ISMN must be 2 or 5 digits) //raiseerror exec
+    } if
+    barcode length 15 ge {  % ISMN-13
+        barcode 0 4 getinterval (979-) ne {
+            /bwipp.ismn13badPrefix (ISMN-13 prefix must be 979-) //raiseerror exec
+        } if
+        /wasdash false def /numdash 0 def /numdigit 0 def
+        barcode 5 9 getinterval {
+            dup
+            45 eq {
+                wasdash {
+                    /bwipp.ismn13adjacentDashes (ISMN-13 does not permit adjacent dashes) //raiseerror exec
+                } if
+                /wasdash true def
+                /numdash numdash 1 add def
+            } if
+            dup 48 ge exch 57 le and {
+                /wasdash false def
+                /numdigit numdigit 1 add def
+            } if
+        } forall
+        numdash 2 ne numdigit 7 ne or {
+            /bwipp.ismn13numDashesDigits (Incorrect number of dashes and digits for ISMN-13) //raiseerror exec
+        } if
+        barcode 14 get dup 48 lt exch 57 gt or {
+            /bwipp.ismn13character15 (ISMN-13 character 15 must be a digit) //raiseerror exec
+        } if
+        barcode length 17 eq {
+            barcode 15 1 getinterval (-) ne {
+                /bwipp.ismn13character16 (ISMN-13 penultimate character must be a dash) //raiseerror exec
+            } if
+            barcode 16 get dup 48 lt exch 57 gt or {
+                /bwipp.ismn13character17 (ISMN-13 final character must be a digit) //raiseerror exec
+            } if
+        } if
+    } {  % ISMN-10
+        barcode 0 2 getinterval (M-) ne {
+            /bwipp.ismn10badPrefix (ISMN-10 prefix must be M-) //raiseerror exec
+        } if
+        barcode 2 get dup 48 lt exch 57 gt or {
+            /bwipp.ismn10character3 (ISMN-10 character 3 must be a digit) //raiseerror exec
+        } if
+        /wasdash false def /numdash 0 def /numdigit 0 def
+        barcode 3 7 getinterval {
+            dup
+            45 eq {
+                wasdash {
+                    /bwipp.ismn10adjacentDashes (ISMN-10 does not permit adjacent dashes) //raiseerror exec
+                } if
+                /wasdash true def
+                /numdash numdash 1 add def
+            } if
+            dup 48 ge exch 57 le and {
+                /wasdash false def
+                /numdigit numdigit 1 add def
+            } if
+        } forall
+        numdash 1 ne numdigit 6 ne or {
+            /bwipp.ismn10numDashesDigits (Incorrect number of dashes and digits for ISMN-10) //raiseerror exec
+        } if
+        barcode 10 get dup 48 lt exch 57 gt or {
+            /bwipp.ismn10character11 (ISMN-10 character 11 must be a digit) //raiseerror exec
+        } if
+        barcode length 13 eq {
+            barcode 11 1 getinterval (-) ne {
+                /bwipp.ismn10character12 (ISMN-10 penultimate character must be a dash) //raiseerror exec
+            } if
+            barcode 12 get dup dup 48 lt exch 57 gt or exch 88 ne and {
+                /bwipp.ismn10character13 (ISMN-10 final character must be a digit or X) //raiseerror exec
+            } if
+        } if
+    } ifelse
+
+    /ismntxt barcode def
+
     % Convert old ISMN to ISMN-13
     /legacytxt () def
-    ismntxt 0 1 getinterval (M) eq ismntxt length 13 le and {
+    ismntxt length 13 le {
         /legacytxt ismntxt def
         /pad ismntxt length 4 add string def
         pad 0 (979-0-) putinterval
@@ -1724,9 +2178,16 @@
         /i i 1 add def
         i ismntxt length eq {exit} if
     } loop
-    /checksum 10 checksum 10 mod sub 10 mod def
-
-    % Add the ISMN header to the ismntxt
+    /checksum 10 checksum 10 mod sub 10 mod 48 add def
+
+    % Validate the checksum
+    barcode length 13 eq barcode length 17 eq or {
+        barcode dup length 1 sub get checksum ne {
+            /bwipp.ismnBadCheckDigit (Incorrect ISMN check digit provided) //raiseerror exec
+        } if
+    } if
+
+    % Add the ISMN header and checksum to the ismntxt
     legacy legacytxt () ne and {
         /ismntxt legacytxt def
         /pad 18 string def
@@ -1734,11 +2195,9 @@
         /pad 22 string def
     } ifelse
     pad 0 (ISMN ) putinterval
-    pad 5 ismntxt putinterval  % Add ismntxt to the pad
-
-    % Add checksum digit
-    pad pad length 2 sub 45 put  % Put a dash
-    pad pad length 1 sub checksum 48 add put  % Put check digit
+    pad 5 ismntxt putinterval
+    pad pad length 2 sub 45 put
+    pad pad length 1 sub checksum put
     /ismntxt pad def
 
     % Convert ISMN digits to EAN-13
@@ -1788,17 +2247,21 @@
 /ismn dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ismn--
 
 % --BEGIN ENCODER issn--
-% --REQUIRES ean13--
-% --SUGGESTS ean2 ean5--
+% --REQUIRES preamble raiseerror renlinear ean2 ean5 ean13--
 % --DESC: ISSN
-% --EXAM: 0317-8471 00 05
+% --EXAM: 0311-175X 00 17
 % --EXOP: includetext guardwhitespace
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp issn 0.0 2014121100 80698 83843
+%%BeginData:        177 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /ean13 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -1841,7 +2304,10 @@
         /issntxt exch def
         pop
         /seqvar exch def
-    } if
+    } { 
+        pop
+        /seqvar () def
+    } ifelse
 
     % Split off the sequence variant and addon
     seqvar ( ) search {
@@ -1850,8 +2316,43 @@
         /addon exch def
     } {
         pop
-        /addon () def
+        /addon seqvar def
+        /seqvar (00) def
     } ifelse
+
+    % Validate the input
+    issntxt length 8 ne issntxt length 9 ne and {
+        /bwipp.issnBadLength (ISSN must be 8 or 9 characters including dash) //raiseerror exec
+    } if
+    issntxt 0 4 getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.issnBadFormat (ISSN must have the format XXXX-XXXX) //raiseerror exec
+        } if
+    } forall
+    issntxt 4 1 getinterval (-) ne {
+        /bwipp.issnBadFormat (ISSN must have the format XXXX-XXXX) //raiseerror exec
+    } if
+    issntxt 5 3 getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.issnBadFormat (ISSN must have the format XXXX-XXXX) //raiseerror exec
+        } if
+    } forall
+    issntxt length 9 eq {
+        issntxt 8 get dup dup 48 lt exch 57 gt or exch 88 ne and {  % Digits or X
+            /bwipp.issnBadFormat (ISSN must have the format XXXX-XXXX) //raiseerror exec
+        } if
+    } if
+    seqvar length 2 ne {
+        /bwipp.issnBadSequenceVariantLength (Sequence variant for ISSN must be 2 digits) //raiseerror exec
+    } if
+    seqvar {
+        dup 48 lt exch 57 gt or {
+           /bwipp.issnSequenceVariantBadCharacter (Sequence variant for ISSN must contain only digits) //raiseerror exec
+        } if
+    } forall
+    addon length 0 ne addon length 2 ne and addon length 5 ne and {
+        /bwipp.issnBadAddOnLength (Add-on for ISSN must be 2 or 5 digits) //raiseerror exec
+    } if
 
     % Read the digits from issntxt and calculate checksums
     /issn 8 string def
@@ -1870,14 +2371,18 @@
         i issntxt length eq {exit} if
     } loop
     /checksum 11 checksum 11 mod sub 11 mod def
-
-    % Add the ISSN header to the issntxt
+    /checksum checksum 48 add dup 58 eq {pop 88} if def
+    issntxt length 9 eq {
+        issntxt 8 get checksum ne {
+            /bwipp.issnBadCheckDigit (Incorrect ISSN check digit provided) //raiseerror exec
+        } if
+    } if
+
+    % Add the ISSN header and checksum to the issntxt
     /pad 14 string def
     pad 0 (ISSN ) putinterval
     pad 5 issntxt putinterval  % Add issntxt to the pad
-
-    % Add checksum digit
-    pad 13 checksum 48 add dup 58 eq {pop 88} if put  % Put check digit
+    pad 13 checksum put
     /issntxt pad def
 
     % Convert ISSN digits to EAN-13
@@ -1931,15 +2436,21 @@
 /issn dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER issn--
 
 % --BEGIN ENCODER code128--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Code 128
 % --EXAM: Count01234567^FNC2!
 % --EXOP: includetext parsefnc
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code128 0.0 2014121100 122003 121439
+%%BeginData:        421 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /code128 {
@@ -2358,16 +2869,21 @@
 /code128 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code128--
 
 % --BEGIN ENCODER gs1-128--
-% --REQUIRES code128--
+% --REQUIRES preamble raiseerror renlinear code128--
 % --DESC: GS1-128
 % --EXAM: (01)95012345678903(3103)000123
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp gs1-128 0.0 2014121100 73938 76998
+%%BeginData:        157 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code128 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -2522,16 +3038,21 @@
 /gs1-128 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER gs1-128--
 
 % --BEGIN ENCODER ean14--
-% --REQUIRES code128--
+% --REQUIRES preamble raiseerror renlinear code128--
 % --DESC: GS1-14
 % --EXAM: (01)04601234567893
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp ean14 0.0 2014121100 63855 67029
+%%BeginData:         93 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code128 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -2567,21 +3088,36 @@
     /textyoffset textyoffset cvr def
     /height height cvr def 
 
-    % Calculate EAN checksum and add to end of barcode
-    barcode length dup 17 eq exch 18 eq or 
-    barcode 0 4 getinterval (\(01\)) eq and {
-        /checksum 0 def
-        0 1 12 {
-            /i exch def
-            /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
-        } for 
-        /checksum 10 checksum 10 mod sub 10 mod def
-        18 string
-        dup 0 barcode 0 17 getinterval putinterval
-        dup 17 checksum 48 add put
-        /barcode exch def
-        /gtin barcode 4 14 getinterval def
-    } if
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.ean14badAI (GS1-14 must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.ean14badLength (GS1-14 must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.ean14badCharacter (GS1-14 must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for 
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.ean14badCheckDigit (Incorrect GS1-14 check digit provided) //raiseerror exec
+        } if
+    } if
+    18 string
+    dup 0 barcode putinterval
+    dup 17 checksum 48 add put
+    /barcode exch def
+    /gtin barcode 4 14 getinterval def
 
     % Compose input to code128
     /text barcode def
@@ -2607,16 +3143,21 @@
 /ean14 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean14--
 
 % --BEGIN ENCODER sscc18--
-% --REQUIRES code128--
+% --REQUIRES preamble raiseerror renlinear code128--
 % --DESC: SSCC-18
 % --EXAM: (00)006141411234567890
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp sscc18 0.0 2014121100 63867 67036
+%%BeginData:         93 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code128 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -2652,21 +3193,36 @@
     /textyoffset textyoffset cvr def
     /height height cvr def 
 
-    % Calculate EAN checksum and add to end of barcode
-    barcode length dup 21 eq exch 22 eq or 
-    barcode 0 4 getinterval (\(00\)) eq and {
-        /checksum 0 def
-        0 1 16 {
-            /i exch def
-            /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
-        } for 
-        /checksum 10 checksum 10 mod sub 10 mod def
-        22 string
-        dup 0 barcode 0 21 getinterval putinterval
-        dup 21 checksum 48 add put
-        /barcode exch def
-        /sscc barcode 4 18 getinterval def
-    } if
+    % Validate the input
+    barcode 0 4 getinterval (\(00\)) ne {
+        /bwipp.sscc18badAI (SSCC-18 must begin with (00) application identifier) //raiseerror exec
+    } if
+    barcode length 21 ne barcode length 22 ne and {
+        /bwipp.sscc18badLength (SSCC-18 must be 17 or 18 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.sscc18badCharacter (SSCC-18 must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 16 {
+        /i exch def
+        /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for 
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 22 eq {
+        barcode 21 get checksum 48 add ne {
+            /bwipp.sscc18badCheckDigit (Incorrect SSCC-18 check digit provided) //raiseerror exec
+        } if
+    } if
+    22 string
+    dup 0 barcode putinterval
+    dup 21 checksum 48 add put
+    /barcode exch def
+    /sscc barcode 4 18 getinterval def
 
     % Compose input to code128
     /text barcode def
@@ -2692,15 +3248,21 @@
 /sscc18 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER sscc18--
 
 % --BEGIN ENCODER code39--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Code 39
 % --EXAM: THIS IS CODE 39
 % --EXOP: includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code39 0.0 2014121100 69000 68552
+%%BeginData:        141 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /code39 {
@@ -2711,7 +3273,8 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
-    /includecheck false def  % Enable/disable checkdigit
+    /includecheck false def
+    /validatecheck false def
     /includetext false def
     /includecheckintext false def
     /hidestars false def
@@ -2735,7 +3298,35 @@
     /textsize textsize cvr def
     /textyoffset textyoffset cvr def
     /height height cvr def
-    
+
+    % Create a string of the available characters
+    /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.code39badCharacter (Code 39 must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 0 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.code39badCheckDigit (Incorrect Code 39 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+        /includecheck true def
+    } if
+
     % Create an array containing the character mappings
     /encs
     [ (1113313111) (3113111131) (1133111131) (3133111111) (1113311131)
@@ -2749,20 +3340,8 @@
       (1313111311) (1311131311) (1113131311) (1311313111)
     ] def
 
-    % Create a string of the available characters
-    /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*) def
-
-    /barlen barcode length def  % Length of the code
-
-    includecheck {
-        /sbs barlen 10 mul 30 add string def
-        /txt barlen 3 add array def
-    } {
-        /sbs barlen 10 mul 20 add string def
-        /txt barlen 2 add array def
-    } ifelse
-
-    /checksum 0 def
+    /sbs barlen includecheck {3} {2} ifelse add 10 mul string def
+    /txt barlen includecheck {3} {2} ifelse add array def
 
     % Put the start character
     sbs 0 encs 43 get putinterval
@@ -2774,20 +3353,13 @@
 
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /enc encs indx get def               % Get the indxth encoding
-        sbs i 10 mul 10 add enc putinterval  % Put encoded digit into sbs
+        /indx charvals barcode i 1 getinterval get def
+        sbs i 10 mul 10 add encs indx get putinterval
         txt i 1 add [barcode i 1 getinterval i 1 add 16 mul textyoffset textfont textsize] put
-        /checksum checksum indx add def
     } for
 
     % Put the checksum and end characters
     includecheck {
-        /checksum checksum 43 mod def
         sbs barlen 10 mul 10 add encs checksum get putinterval
         includecheckintext {
             txt barlen 1 add [barchars checksum 1 getinterval barlen 1 add 16 mul textyoffset textfont textsize] put
@@ -2829,16 +3401,21 @@
 /code39 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code39--
 
 % --BEGIN ENCODER code39ext--
-% --REQUIRES code39--
+% --REQUIRES preamble raiseerror renlinear code39--
 % --DESC: Code 39 Extended
 % --EXAM: Code39 Ext!
 % --EXOP: includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code39ext 0.0 2014121100 67871 70945
+%%BeginData:        110 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code39 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -2885,6 +3462,13 @@
         } loop
     } if
 
+    % Validate the input
+    barcode 4 barcode length 4 sub getinterval {
+        128 ge {
+            /bwipp.code39extBadCharacter (Code 39 Extended must contain only ASCII characters) //raiseerror exec
+        } if
+    } forall
+
     /barlen barcode length def
 
     % Extended alphabet to non-extended alphabet
@@ -2939,16 +3523,21 @@
 /code39ext dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code39ext--
 
 % --BEGIN ENCODER code32--
-% --REQUIRES code39--
-% --DESC: Italian PharmaCode
+% --REQUIRES preamble raiseerror renlinear code39--
+% --DESC: Italian Pharmacode
 % --EXAM: 01234567
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code32 0.0 2014121100 64608 67911
+%%BeginData:         99 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code39 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -2983,15 +3572,33 @@
     /textyoffset textyoffset cvr def
     /height height cvr def
 
-    /text 10 string def
-    text 0 barcode 0 8 getinterval putinterval
-
-    % calculate check digit
-    text 8 0
+    % Validate the input
+    barcode length 8 ne barcode length 9 ne and {
+        /bwipp.code32badLength (Italian Pharmacode must be 8 or 9 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.code32badCharacter (Italian Pharmacode must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate check digit
+    /checksum 0 def
     0 1 7 {
-        dup text exch get 48 sub exch 1 and 1 add mul dup 9 gt {9 sub} if add
+        /i exch def
+        barcode i get 48 sub i 2 mod 0 ne {2 mul} if dup 9 gt {9 sub} if
+        checksum add /checksum exch def
     } for
-    10 mod 48 add put
+    /checksum checksum 10 mod def
+    barcode length 9 eq {
+        barcode 8 get checksum 48 add ne {
+            /bwipp.code32badCheckDigit (Incorrect Italian Pharmacode check digit provided) //raiseerror exec
+        } if
+    } if
+    10 string
+    dup 0 barcode putinterval
+    dup 8 checksum 48 add put
+    /text exch def
 
     % convert number from base10 to base32
     /val text cvi 32 barcode cvrs def
@@ -3027,16 +3634,21 @@
 /code32 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code32--
 
 % --BEGIN ENCODER pzn--
-% --REQUIRES code39--
+% --REQUIRES preamble raiseerror renlinear code39--
 % --DESC: Pharmazentralnummer (PZN)
 % --EXAM: 123456
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp pzn 0.0 2014121100 64783 67907
+%%BeginData:        100 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code39 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -3073,16 +3685,44 @@
     /textxoffset textxoffset cvr def
     /height height cvr def
 
-    /msg pzn8 {9} {8} ifelse string def
-    /msglen msg length def
-    msg 0 45 put 
-    msg 1 barcode 0 msglen 2 sub getinterval putinterval
- 
-    % calculate check digit
-    0 
-    1 1 msglen 2 sub {dup msg exch get 48 sub exch pzn8 not {1 add} if mul add} for
-    11 mod 48 add
-    msg exch msglen 1 sub exch put
+    % Validate the input
+    pzn8 {
+        barcode length 7 ne barcode length 8 ne and {
+            /bwipp.pzn8badLength (PZN8 must be 7 or 8 digits) //raiseerror exec
+        } if
+    } {
+        barcode length 6 ne barcode length 7 ne and {
+            /bwipp.pzn7badLength (PZN7 must be 6 or 7 digits) //raiseerror exec
+        } if
+    } ifelse
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.pznBadCharacter (PZN must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate check digit
+    /msglen pzn8 {9} {8} ifelse def
+    /checksum 0 def
+    0 1 msglen 3 sub {
+        /i exch def
+        barcode i get 48 sub i pzn8 {1} {2} ifelse add mul
+        checksum add /checksum exch def 
+    } for 
+    /checksum checksum 11 mod def
+    checksum 10 eq {
+        /bwipp.pznBadInputSequence (Incorrect PZN input sequence provided) //raiseerror exec
+    } if
+    barcode length msglen 1 sub eq {
+        barcode msglen 2 sub get checksum 48 add ne {
+            /bwipp.pznBadCheckDigit (Incorrect PZN check digit provided) //raiseerror exec
+        } if
+    } if
+    msglen string
+    dup 0 45 put 
+    dup 1 barcode putinterval
+    dup msglen 1 sub checksum 48 add put
+    /msg exch def
  
     % Get the result of encoding with code39
     options (dontdraw) true put
@@ -3106,15 +3746,21 @@
 /pzn dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER pzn--
 
 % --BEGIN ENCODER code93--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Code 93
 % --EXAM: THIS IS CODE 93
 % --EXOP: includetext includecheck
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code93 0.0 2014121100 67695 67503
+%%BeginData:        148 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /code93 {
@@ -3260,16 +3906,21 @@
 /code93 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code93--
 
 % --BEGIN ENCODER code93ext--
-% --REQUIRES code93--
+% --REQUIRES preamble raiseerror renlinear code93--
 % --DESC: Code 93 Extended
 % --EXAM: Code93 Ext!
 % --EXOP: includetext includecheck
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code93ext 0.0 2014121100 68040 71146
+%%BeginData:        114 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /code93 dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -3381,15 +4032,21 @@
 /code93ext dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code93ext--
 
 % --BEGIN ENCODER interleaved2of5--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Interleaved 2 of 5 (ITF)
 % --EXAM: 2401234567
 % --EXOP: height=0.5 includecheck includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp interleaved2of5 0.0 2014121100 67459 67031
+%%BeginData:        150 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /interleaved2of5 {
@@ -3423,6 +4080,13 @@
     /textsize textsize cvr def
     /textyoffset textyoffset cvr def
     /height height cvr def
+
+    % Validate the input
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.interleaved2of5badCharacter (Interleaved 2 of 5 must contain only digits) //raiseerror exec
+        } if
+    } forall
     
     /barlen barcode length def      % Length of the code
 
@@ -3530,20 +4194,132 @@
 /interleaved2of5 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER interleaved2of5--
 
 % --BEGIN ENCODER itf14--
-% --REQUIRES interleaved2of5--
+% --REQUIRES preamble raiseerror renlinear interleaved2of5--
 % --DESC: ITF-14
 % --EXAM: 04601234567893
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp itf14 0.0 2014121100 63768 66890
+%%BeginData:         95 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /interleaved2of5 dup /uk.co.terryburton.bwipp findresource put
 begin
 /itf14 {
+
+    20 dict begin            % Confine variables to local scope
+
+    /options exch def  % We are given an option string
+    /barcode exch def  % We are given a barcode string
+
+    /dontdraw false def
+    /includetext false def
+    /includecheckintext true def
+    /textfont /Courier def
+    /textsize 10 def
+    /textxoffset 0 def
+    /textyoffset -10 def
+    /height 0.5 def
+    /showborder true def
+    /borderwidth 4 def
+    /borderleft 15 def
+    /borderright 15 def
+ 
+    % Parse the input options
+    options type /stringtype eq {
+        1 dict begin
+        options {
+            token false eq {exit} if dup length string cvs (=) search
+            true eq {cvlit exch pop exch def} {cvlit true def} ifelse
+        } loop
+        currentdict end /options exch def
+    } if
+    options {def} forall
+
+    /textfont textfont cvlit def
+    /textsize textsize cvr def
+    /textxoffset textxoffset cvr def
+    /textyoffset textyoffset cvr def
+    /height height cvr def 
+    /borderwidth borderwidth cvr def
+    /borderleft borderleft cvr def
+    /borderright borderright cvr def
+
+    % Validate the input
+    barcode length 13 ne barcode length 14 ne and {
+        /bwipp.itf14badLength (ITF-14 must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.itf14badCharacter (ITF-14 must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate ITF checksum and add to end of barcode
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 14 eq {
+        barcode 13 get checksum 48 add ne {
+            /bwipp.itf14badCheckDigit (Incorrect ITF-14 check digit provided) //raiseerror exec
+        } if
+    } if
+    14 string
+    dup 0 barcode putinterval
+    dup 13 checksum 48 add put
+    /barcode exch def
+
+    % Get the result of encoding with interleaved2of5
+    options (dontdraw) true put
+    options (showborder) showborder put
+    options (borderwidth) borderwidth put
+    options (borderleft) borderleft put
+    options (borderright) borderright put
+    options (height) height put
+    options (textyoffset) textyoffset put
+    options (includecheckintext) includecheckintext put
+    /args barcode options //interleaved2of5 exec def
+
+    args (opt) options put
+    args
+ 
+    dontdraw not //renlinear if
+ 
+    end
+
+} bind def
+/itf14 dup load /uk.co.terryburton.bwipp defineresource pop
+end
+/setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
+% --END ENCODER itf14--
+
+% --BEGIN ENCODER identcode--
+% --REQUIRES preamble raiseerror renlinear interleaved2of5--
+% --DESC: Deutsche Post Identcode
+% --EXAM: 563102430313
+% --EXOP: includetext
+% --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp identcode 0.0 2014121100 63813 66907
+%%BeginData:         91 ASCII Lines
+/setpacking where {pop currentpacking true setpacking} if
+1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
+dup /renlinear dup /uk.co.terryburton.bwipp findresource put
+dup /interleaved2of5 dup /uk.co.terryburton.bwipp findresource put
+begin
+/identcode {
 
     20 dict begin            % Confine variables to local scope
 
@@ -3575,23 +4351,48 @@
     /textyoffset textyoffset cvr def
     /height height cvr def 
 
-    % Calculate EAN checksum and add to end of barcode
-    barcode length dup 13 eq exch 14 eq or {
-        /gtin barcode 0 13 getinterval def
-    } if
+    % Validate the input
+    barcode length 11 ne barcode length 12 ne and {
+        /bwipp.identcodeBadLength (Deutsche Post Identcode must be 11 or 12 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.identcodeBadCharacter (Deutsche Post Identcode must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 10 {
+        /i exch def
+        /checksum checksum barcode i get 48 sub i 2 mod 0 eq {4 mul} {9 mul} ifelse add def
+    } for 
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 12 eq {
+        barcode 11 get checksum 48 add ne {
+            /bwipp.identcodeBadCheckDigit (Incorrect Deutsche Post Identcode check digit provided) //raiseerror exec
+        } if
+    } if
+    12 string
+    dup 0 barcode putinterval
+    dup 11 checksum 48 add put
+    /barcode exch def
+
+    % Compose the human readable text
+    /text (  .       .     ) 16 string copy def
+    text  0 barcode  0 2 getinterval putinterval
+    text  3 barcode  2 3 getinterval putinterval
+    text  7 barcode  5 3 getinterval putinterval
+    text 11 barcode  8 3 getinterval putinterval
+    text 15 barcode 11 1 getinterval putinterval
 
     % Get the result of encoding with interleaved2of5
     options (dontdraw) true put
-    options (showborder) true put
-    options (borderwidth) 4 put
-    options (borderleft) 15 put
-    options (borderright) 15 put
-    options (height) 0.5 put
-    options (includecheck) true put
-    options (includecheckintext) true put
-    options (textyoffset) -10 put
-    /args gtin options //interleaved2of5 exec def
-
+    options (includecheck) false put
+    /args barcode options //interleaved2of5 exec def
+
+    args (txt) [ [text textxoffset textyoffset textfont textsize] ] put
+    args (textxalign) (center) put
     args (opt) options put
     args
  
@@ -3600,23 +4401,28 @@
     end
 
 } bind def
-/itf14 dup load /uk.co.terryburton.bwipp defineresource pop
+/identcode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER itf14--
-
-% --BEGIN ENCODER identcode-- 
-% --REQUIRES interleaved2of5--
-% --DESC: Deutsche Post Identcode
-% --EXAM: 563102430313
+%%EndData
+%%EndResource
+% --END ENCODER identcode--
+
+% --BEGIN ENCODER leitcode--
+% --REQUIRES preamble raiseerror renlinear interleaved2of5--
+% --DESC: Deutsche Post Leitcode
+% --EXAM: 21348075016401
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp leitcode 0.0 2014121100 63805 66903
+%%BeginData:         91 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /interleaved2of5 dup /uk.co.terryburton.bwipp findresource put
 begin
-/identcode {
+/leitcode {
 
     20 dict begin            % Confine variables to local scope
 
@@ -3648,28 +4454,40 @@
     /textyoffset textyoffset cvr def
     /height height cvr def 
 
+    % Validate the input
+    barcode length 13 ne barcode length 14 ne and {
+        /bwipp.leitcodeBadLength (Deutsche Post Leitcode must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.leitcodeBadCharacter (Deutsche Post Leitcode must contain only digits) //raiseerror exec
+        } if
+    } forall
+
     % Calculate checksum and add to end of barcode
-    barcode length dup 11 eq exch 12 eq or {
-        /checksum 0 def
-        0 1 10 {
-            /i exch def
-            /checksum checksum barcode i get 48 sub i 2 mod 0 eq {4 mul} {9 mul} ifelse add def
-        } for 
-        /checksum 10 checksum 10 mod sub 10 mod def
-        12 string
-        dup 0 barcode 0 11 getinterval putinterval
-        dup 11 checksum 48 add put
-        /pad exch def
-    } if
-    /barcode pad def
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i get 48 sub i 2 mod 0 eq {4 mul} {9 mul} ifelse add def
+    } for 
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 14 eq {
+        barcode 13 get checksum 48 add ne {
+            /bwipp.leitcodeBadCheckDigit (Incorrect Deutsche Post Leitcode check digit provided) //raiseerror exec
+        } if
+    } if
+    14 string
+    dup 0 barcode putinterval
+    dup 13 checksum 48 add put
+    /barcode exch def
 
     % Compose the human readable text
-    /text (  .       .     ) 16 string copy def
-    text  0 barcode  0 2 getinterval putinterval
-    text  3 barcode  2 3 getinterval putinterval
-    text  7 barcode  5 3 getinterval putinterval
-    text 11 barcode  8 3 getinterval putinterval
-    text 15 barcode 11 1 getinterval putinterval
+    /text (     .   .   .    ) 18 string copy def
+    text  0 barcode  0 5 getinterval putinterval
+    text  6 barcode  5 3 getinterval putinterval
+    text 10 barcode  8 3 getinterval putinterval
+    text 14 barcode 11 2 getinterval putinterval
+    text 17 barcode 13 1 getinterval putinterval
 
     % Get the result of encoding with interleaved2of5
     options (dontdraw) true put
@@ -3686,104 +4504,24 @@
     end
 
 } bind def
-/identcode dup load /uk.co.terryburton.bwipp defineresource pop
-end
-/setpacking where {pop setpacking} if
-% --END ENCODER identcode--
-
-% --BEGIN ENCODER leitcode-- 
-% --REQUIRES interleaved2of5--
-% --DESC: Deutsche Post Leitcode
-% --EXAM: 21348075016401
-% --EXOP: includetext
-% --RNDR: renlinear
-/setpacking where {pop currentpacking true setpacking} if
-1 dict
-dup /renlinear dup /uk.co.terryburton.bwipp findresource put
-dup /interleaved2of5 dup /uk.co.terryburton.bwipp findresource put
-begin
-/leitcode {
-
-    20 dict begin            % Confine variables to local scope
-
-    /options exch def  % We are given an option string
-    /barcode exch def  % We are given a barcode string
-
-    /dontdraw false def
-    /includetext false def    % Enable/disable text
-    /textfont /Courier def
-    /textsize 10 def
-    /textxoffset 0 def
-    /textyoffset -7 def
-    /height 1 def
- 
-    % Parse the input options
-    options type /stringtype eq {
-        1 dict begin
-        options {
-            token false eq {exit} if dup length string cvs (=) search
-            true eq {cvlit exch pop exch def} {cvlit true def} ifelse
-        } loop
-        currentdict end /options exch def
-    } if
-    options {def} forall
-
-    /textfont textfont cvlit def
-    /textsize textsize cvr def
-    /textxoffset textxoffset cvr def
-    /textyoffset textyoffset cvr def
-    /height height cvr def 
-
-    % Calculate checksum and add to end of barcode
-    barcode length dup 13 eq exch 14 eq or {
-        /checksum 0 def
-        0 1 12 {
-            /i exch def
-            /checksum checksum barcode i get 48 sub i 2 mod 0 eq {4 mul} {9 mul} ifelse add def
-        } for 
-        /checksum 10 checksum 10 mod sub 10 mod def
-        14 string
-        dup 0 barcode 0 13 getinterval putinterval
-        dup 13 checksum 48 add put
-        /pad exch def
-    } if
-    /barcode pad def
-
-    % Compose the human readable text
-    /text (     .   .   .    ) 18 string copy def
-    text  0 barcode  0 5 getinterval putinterval
-    text  6 barcode  5 3 getinterval putinterval
-    text 10 barcode  8 3 getinterval putinterval
-    text 14 barcode 11 2 getinterval putinterval
-    text 17 barcode 13 1 getinterval putinterval
-
-    % Get the result of encoding with interleaved2of5
-    options (dontdraw) true put
-    options (includecheck) false put
-    /args barcode options //interleaved2of5 exec def
-
-    args (txt) [ [text textxoffset textyoffset textfont textsize] ] put
-    args (textxalign) (center) put
-    args (opt) options put
-    args
- 
-    dontdraw not //renlinear if
- 
-    end
-
-} bind def
 /leitcode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER leitcode--
 
 % --BEGIN ENCODER databaromni--
+% --REQUIRES preamble raiseerror renlinear renmatrix--
 % --DESC: GS1 DataBar Omnidirectional
 % --EXAM: (01)24012345678905
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databaromni 0.0 2014121100 113396 115580
+%%BeginData:        418 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -3813,25 +4551,33 @@
     format (truncated) eq {/height 13 72 div def} if
     /height height cvr def
 
-    % Strip the AI and optional check digit
-    barcode length dup 17 eq exch 18 eq or {
-        barcode 0 4 getinterval (\(01\)) eq {
-            /binval [ 
-                linkage {1} {0} ifelse
-                barcode 4 13 getinterval {48 sub} forall
-            ] def
-        } if
-    } if
-
-    % Calculate EAN checksum and add to end of barcode
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.databaromniBadAI (GS1 DataBar Omnidirectional must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.databaromniBadLength (GS1 DataBar Omnidirectional must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.databaromniBadCharacter (GS1 DataBar Omnidirectional must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
     /checksum 0 def
     0 1 12 {
         /i exch def
         /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
-    } for 
+    } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.databaromniBadCheckDigit (Incorrect GS1 DataBar Omnidirectional check digit provided) //raiseerror exec
+        } if
+    } if
     18 string
-    dup 0 barcode 0 17 getinterval putinterval
+    dup 0 barcode putinterval
     dup 17 checksum 48 add put
     /barcode exch def
 
@@ -3896,7 +4642,12 @@
         out el 1 sub nm put
         out
     } bind def
-   
+  
+    /binval [ 
+        linkage {1} {0} ifelse
+        barcode 4 13 getinterval {48 sub} forall
+    ] def
+ 
     0 1 12 {
         /i exch def
         binval i 1 add 2 copy get binval i get 4537077 mod 10 mul add put
@@ -4186,16 +4937,21 @@
 /databaromni dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databaromni--
 
 % --BEGIN ENCODER databarstacked--
-% --REQUIRES databaromni--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni--
 % --DESC: GS1 DataBar Stacked
 % --EXAM: (01)24012345678905
 % --EXOP:
-% --RNDR: renmatrix renlinear
+% --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarstacked 0.0 2014121100 68587 65080
+%%BeginData:         73 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 dup /databaromni dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -4219,6 +4975,36 @@
     } if
     options {def} forall
 
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.databarstackedBadAI (GS1 DataBar Stacked must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.databarstackedBadLength (GS1 DataBar Stacked must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.databarstackedBadCharacter (GS1 DataBar Stacked must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.databarstackedBadCheckDigit (Incorrect GS1 DataBar Stacked check digit provided) //raiseerror exec
+        } if
+    } if
+    18 string
+    dup 0 barcode putinterval
+    dup 17 checksum 48 add put
+    /barcode exch def
+
     % Get the result of encoding with databaromni with format=stacked
     options (dontdraw) true put
     options (format) (stacked) put
@@ -4236,16 +5022,21 @@
 /databarstacked dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarstacked--
 
 % --BEGIN ENCODER databarstackedomni--
-% --REQUIRES databaromni--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni--
 % --DESC: GS1 DataBar Stacked Omnidirectional
 % --EXAM: (01)24012345678905
 % --EXOP:
-% --RNDR: renmatrix renlinear
+% --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarstackedomni 0.0 2014121100 68687 65056
+%%BeginData:         73 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 dup /databaromni dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -4269,6 +5060,36 @@
     } if
     options {def} forall
 
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.databarstackedomniBadAI (GS1 DataBar Stacked Omnidirectional must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.databarstackedomniBadLength (GS1 DataBar Stacked Omnidirectional must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.databarstackedomniBadCharacter (GS1 DataBar Stacked Omnidirectional must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.databarstackedomniBadCheckDigit (Incorrect GS1 DataBar Stacked Omnidirectional check digit provided) //raiseerror exec
+        } if
+    } if
+    18 string
+    dup 0 barcode putinterval
+    dup 17 checksum 48 add put
+    /barcode exch def
+
     % Get the result of encoding with databaromni with format=stackedomni
     options (dontdraw) true put
     options (format) (stackedomni) put
@@ -4286,16 +5107,21 @@
 /databarstackedomni dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarstackedomni--
 
 % --BEGIN ENCODER databartruncated--
-% --REQUIRES databaromni--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni--
 % --DESC: GS1 DataBar Truncated
 % --EXAM: (01)24012345678905
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databartruncated 0.0 2014121100 68613 65096
+%%BeginData:         73 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /databaromni dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -4319,6 +5145,36 @@
     } if
     options {def} forall
 
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.databartruncatedBadAI (GS1 DataBar Truncated must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.databartruncatedBadLength (GS1 DataBar Truncated must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 barcode length 4 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.databartruncatedBadCharacter (GS1 DataBar Truncated must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
+    /checksum 0 def
+    0 1 12 {
+        /i exch def
+        /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.databartruncatedBadCheckDigit (Incorrect GS1 DataBar Truncated check digit provided) //raiseerror exec
+        } if
+    } if
+    18 string
+    dup 0 barcode putinterval
+    dup 17 checksum 48 add put
+    /barcode exch def
+
     % Get the result of encoding with databaromni with format=truncated
     options (dontdraw) true put
     options (format) (truncated) put
@@ -4336,15 +5192,21 @@
 /databartruncated dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databartruncated--
 
 % --BEGIN ENCODER databarlimited--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: GS1 DataBar Limited
 % --EXAM: (01)15012345678907
 % --EXOP:
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp databarlimited 0.0 2014121100 86959 85912
+%%BeginData:        276 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /databarlimited {
@@ -4371,33 +5233,50 @@
    
     /height height cvr def
 
-    % Strip the AI and optional check digit
-    barcode length dup 17 eq exch 18 eq or {
-        barcode 0 5 getinterval dup (\(01\)0) eq exch (\(01\)1) eq or {
-            /binval [ 
-                barcode 4 13 getinterval {48 sub} forall
-            ] def
-            linkage {
-                /linkval [ 2 0 1 5 1 3 3 5 3 1 0 9 6 ] def
-                0 1 binval length 1 sub {
-                    /i exch def
-                    binval i binval i get linkval i get add put
-                } for
-            } if 
-        } if
-    } if
-
-    % Calculate EAN checksum and add to end of barcode
+    % Validate the input
+    barcode 0 4 getinterval (\(01\)) ne {
+        /bwipp.databarlimitedBadAI (GS1 DataBar Limited must begin with (01) application identifier) //raiseerror exec
+    } if
+    barcode length 17 ne barcode length 18 ne and {
+        /bwipp.databarlimitedBadLength (GS1 DataBar Limited must be 13 or 14 digits) //raiseerror exec
+    } if
+    barcode 4 get dup 48 lt exch 49 gt or {
+        /bwipp.databarlimitedBadStartDigit (GS1 DataBar Limited must begin with 0 or 1) //raiseerror exec
+    } if
+    barcode 5 barcode length 5 sub getinterval {
+        dup 48 lt exch 57 gt or {
+            /bwipp.databarlimitedBadCharacter (GS1 DataBar Limited must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Calculate checksum and add to end of barcode
     /checksum 0 def
     0 1 12 {
         /i exch def
         /checksum checksum barcode i 4 add get 48 sub i 2 mod 0 eq {3 mul} if add def
-    } for 
+    } for
     /checksum 10 checksum 10 mod sub 10 mod def
+    barcode length 18 eq {
+        barcode 17 get checksum 48 add ne {
+            /bwipp.databaromniBadCheckDigit (Incorrect GS1 DataBar Limited check digit provided) //raiseerror exec
+        } if
+    } if
     18 string
-    dup 0 barcode 0 17 getinterval putinterval
+    dup 0 barcode putinterval
     dup 17 checksum 48 add put
     /barcode exch def
+
+    % Strip the AI and optional check digit
+    /binval [ 
+        barcode 4 13 getinterval {48 sub} forall
+    ] def
+    linkage {
+        /linkval [ 2 0 1 5 1 3 3 5 3 1 0 9 6 ] def
+        0 1 binval length 1 sub {
+            /i exch def
+            binval i binval i get linkval i get add put
+        } for
+    } if 
 
     % Create the human readable text
     /txt barcode length array def
@@ -4601,15 +5480,21 @@
 /databarlimited dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarlimited--
 
 % --BEGIN ENCODER databarexpanded--
+% --REQUIRES preamble raiseerror renlinear renmatrix--
 % --DESC: GS1 DataBar Expanded
 % --EXAM: (01)95012345678903(3103)000123
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarexpanded 0.0 2014121100 199499 218773
+%%BeginData:        871 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -5478,16 +6363,21 @@
 /databarexpanded dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarexpanded--
 
 % --BEGIN ENCODER databarexpandedstacked--
-% --REQUIRES databarexpanded--
+% --REQUIRES preamble raiseerror renlinear renmatrix databarexpanded--
 % --DESC: GS1 DataBar Expanded Stacked
 % --EXAM: (01)95012345678903(3103)000123
 % --EXOP: segments=4
-% --RNDR: renmatrix renlinear
+% --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarexpandedstacked 0.0 2014121100 67280 63708
+%%BeginData:         43 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 dup /databarexpanded dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -5528,15 +6418,21 @@
 /databarexpandedstacked dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarexpandedstacked--
 
 % --BEGIN ENCODER pharmacode--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Pharmaceutical Binary Code
 % --EXAM: 117480
 % --EXOP: showborder
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp pharmacode 0.0 2014121100 61048 60791
+%%BeginData:         91 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /pharmacode {
@@ -5567,6 +6463,19 @@
     /nwidth nwidth cvr def
     /wwidth wwidth cvr def
     /swidth swidth cvr def
+
+    % Validate the input
+    barcode length 1 lt barcode length 6 gt or {
+        /bwipp.pharmacodeBadLength (Pharmacode must be 1 to 6 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.pharmacodeBadCharacter (Pharmacode must contain only digits) //raiseerror exec
+        } if
+    } forall
+    barcode cvi dup 3 lt exch 131070 gt or {
+        /bwipp.pharmacodeBadValue (Pharmacode value must be between 3 and 131070) //raiseerror exec
+    } if
 
     % Create the human readable text
     /txt barcode length array def
@@ -5612,15 +6521,21 @@
 /pharmacode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER pharmacode--
 
 % --BEGIN ENCODER pharmacode2--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Two-track Pharmacode
 % --EXAM: 117480
 % --EXOP: includetext showborder
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp pharmacode2 0.0 2014121100 61823 61489
+%%BeginData:         96 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /pharmacode2 {
@@ -5646,6 +6561,19 @@
     options {def} forall
 
     /height height cvr def
+
+    % Validate the input
+    barcode length 1 lt barcode length 8 gt or {
+        /bwipp.pharmacode2BadLength (Two-track Pharmacode must be 1 to 6 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.pharmacode2badCharacter (Two-track Pharmacode must contain only digits) //raiseerror exec
+        } if
+    } forall
+    barcode cvi dup 4 lt exch 64570080 gt or {
+        /bwipp.pharmacode2badValue (Two-track Pharmacode value must be between 4 and 64570080) //raiseerror exec
+    } if
 
     % Create the human readable text
     /txt barcode length array def
@@ -5701,15 +6629,21 @@
 /pharmacode2 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER pharmacode2--
 
 % --BEGIN ENCODER code2of5--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Code 25
 % --EXAM: 01234567
 % --EXOP: version=iata includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code2of5 0.0 2014121100 69481 69040
+%%BeginData:        150 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /code2of5 {
@@ -5721,6 +6655,7 @@
 
     /dontdraw false def
     /includecheck false def
+    /validatecheck false def
     /includetext false def   % Enable/disable text
     /includecheckintext false def
     /textfont /Courier def
@@ -5745,8 +6680,31 @@
     /textyoffset textyoffset cvr def
     /height height cvr def
 
+    % Validate input
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.code2of5badCharacter (Code 25 must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 0 def
+    0 1 barlen 1 sub {
+        /i exch def
+        /checksum checksum barcode i get 48 sub barlen i sub 2 mod 0 ne {3 mul} if add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    validatecheck {
+        barcode barlen get checksum 48 add ne {
+            /bwipp.code2of5badCheckDigit (Incorrect Code 25 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+        /includecheck true def
+    } if
+
     % Create an array containing the character mappings
-    << 
+    /versions << 
     /industrial
         [ (1111313111) (3111111131) (1131111131) (3131111111)
           (1111311131) (3111311111) (1131311111) (1111113131)
@@ -5769,8 +6727,12 @@
         [ (113311) (311131) (131131) (331111) (113131) (313111)
           (133111) (111331) (311311) (131311) (1111)   (311)
         ]
-    >>
-    version get /encs exch def
+    >> def
+    versions version known not {
+        /bwipp.code2of5badVersion (Unrecognised Code 25 version) //raiseerror exec
+    } if
+    /encs versions version get def
+
     /cs encs 0 get length def
     /cw 0 encs 0 get {48 sub add} forall def
     /ss encs dup length 2 sub get length def
@@ -5779,21 +6741,11 @@
     % Create a string of the available characters
     /barchars (0123456789) def
 
-    /barlen barcode length def            % Length of the code
-
-    includecheck {
-        /sbs barlen 1 add cs mul ss add ss add string def
-        /txt barlen 1 add array def
-    } {
-        /sbs barlen cs mul ss add ss add string def
-        /txt barlen array def
-    } ifelse
+    /sbs barlen includecheck {1 add} if cs mul ss add ss add string def
+    /txt barlen includecheck {1 add} if array def
 
     % Put the start character
     sbs 0 encs 10 get putinterval
-
-    /checksum 0 def
-
     0 1 barlen 1 sub {
         /i exch def
         % Lookup the encoding for the each barcode character
@@ -5804,16 +6756,10 @@
         /enc encs indx get def              % Get the indxth encoding
         sbs i cs mul ss add enc putinterval % Put encoded digit into sbs
         txt i [barcode i 1 getinterval i cw mul sw add textyoffset textfont textsize] put
-        barlen i sub 2 mod 0 eq {
-            /checksum checksum indx add def
-        } {
-            /checksum checksum indx 3 mul add def
-        } ifelse
     } for
 
     % Put the checksum and end characters
     includecheck {
-        /checksum 10 checksum 10 mod sub 10 mod def
         sbs barlen cs mul ss add encs checksum get putinterval
         sbs barlen cs mul cs add ss add encs 11 get putinterval
         includecheckintext {
@@ -5845,15 +6791,21 @@
 /code2of5 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code2of5--
 
 % --BEGIN ENCODER code11--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Code 11
 % --EXAM: 0123456789
 % --EXOP: includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp code11 0.0 2014121100 70977 70345
+%%BeginData:        158 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /code11 {
@@ -5865,6 +6817,7 @@
 
     /dontdraw false def
     /includecheck false def
+    /validatecheck false def
     /includetext false def
     /includecheckintext false def
     /textfont /Courier def
@@ -5897,50 +6850,70 @@
 
     % Create a string of the available characters
     /barchars (0123456789-) def
-
-    /barlen barcode length def        % Length of the code
-
-    includecheck {
-        barlen 10 ge {
-            /sbs barlen 6 mul 24 add string def
-            /txt barlen 2 add array def
+    /charvals 11 dict def
+    0 1 10 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.code11badCharacter (Code 11 must contain only digits and dashes) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length def
+    validatecheck {
+        barlen 11 eq {
+            /bwipp.code11badLength (Code 11 cannot be 11 characters using check digits) //raiseerror exec
+        } if
+        /barlen barlen barlen 10 le {1} {2} ifelse sub def
+    } if
+
+    /numchecks includecheck validatecheck or {barlen 10 ge {2} {1} ifelse} {0} ifelse def
+    /checksum1 0 def /checksum2 0 def
+    0 1 barlen 1 sub {
+        /i exch def
+        /indx charvals barcode i 1 getinterval get def
+        /checksum1 checksum1 barlen i sub 1 sub 10 mod 1 add indx mul add def
+        /checksum2 checksum2 barlen i sub 9 mod 1 add indx mul add def
+    } for
+    /checksum1 checksum1 11 mod def
+    /checksum2 checksum2 checksum1 add 11 mod def
+    validatecheck {
+        numchecks 1 eq {
+            barcode barlen get barchars checksum1 get ne {
+                /bwipp.code11badCheckDigit (Incorrect Code 11 check digit provided) //raiseerror exec
+            } if
         } {
-            /sbs barlen 6 mul 18 add string def
-            /txt barlen 1 add array def
+            barcode barlen get barchars checksum1 get ne
+            barcode barlen 1 add get barchars checksum2 get ne or {
+                /bwipp.code11badCheckDigits (Incorrect Code 11 check digits provided) //raiseerror exec
+            } if
         } ifelse
-    } {
-        /sbs barlen 6 mul 12 add string def
-        /txt barlen array def
-    } ifelse
+        /barcode barcode 0 barlen getinterval def
+        /includecheck true def
+    } if
+
+    /sbs barlen numchecks add 6 mul 12 add string def
+    /txt barlen numchecks add array def
 
     % Put the start character
     sbs 0 encs 11 get putinterval
 
-    /checksum1 0 def /checksum2 0 def
-    
     /xpos 8 def
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                % Discard true leaving pre
-        length /indx exch def              % indx is the length of pre
-        pop pop                            % Discard seek and post
-        /enc encs indx get def             % Get the indxth encoding
-        sbs i 6 mul 6 add enc putinterval  % Put encoded digit into sbs
+        /indx charvals barcode i 1 getinterval get def
+        /enc encs indx get def
+        sbs i 6 mul 6 add enc putinterval
         txt i [barcode i 1 getinterval xpos textyoffset textfont textsize] put
         0 1 5 {       % xpos+=width of the character
             /xpos exch enc exch get 48 sub xpos add def
         } for
-        /checksum1 checksum1 barlen i sub 1 sub 10 mod 1 add indx mul add def
-        /checksum2 checksum2 barlen i sub 9 mod 1 add indx mul add def
     } for
    
     % Put the checksum and end characters
     includecheck {
-        /checksum1 checksum1 11 mod def        
         barlen 10 ge {
-            /checksum2 checksum2 checksum1 add 11 mod def
             sbs barlen 6 mul 6 add encs checksum1 get putinterval        
             sbs barlen 6 mul 12 add encs checksum2 get putinterval
             includecheckintext {
@@ -5988,15 +6961,21 @@
 /code11 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code11--
 
 % --BEGIN ENCODER bc412--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: BC412
 % --EXAM: BC412
 % --EXOP: semi includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp bc412 0.0 2014121100 66446 66096
+%%BeginData:        148 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /bc412 {
@@ -6007,7 +6986,8 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
-    /includecheck false def  % Enable/disable checkdigit
+    /includecheck false def
+    /validatecheck false def
     /includetext false def
     /includecheckintext false def
     /includestartstop false def
@@ -6037,7 +7017,35 @@
         /includecheck true def
         /includestartstop true def
     } if
- 
+
+    % Create a string of the available characters
+    /barchars (0R9GLVHA8EZ4NTS1J2Q6C7DYKBUIX3FWP5M) def
+    /charvals 35 dict def
+    0 1 34 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.bc412badCharacter (BC412 must contain only digits and capital letters except O) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 0 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 35 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.bc412badCheckDigit (Incorrect BC412 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+        /includecheck true def
+    } if
+
     % Create an array containing the character mappings
     /encs
     [ (11111115) (13111212) (11131113) (12111213) (12121311)
@@ -6050,11 +7058,6 @@
       (12) (111)
     ] def
 
-    % Create a string of the available characters
-    /barchars (0R9GLVHA8EZ4NTS1J2Q6C7DYKBUIX3FWP5M) def
-
-    /barlen barcode length def  % Length of the code
-
     /sbs barlen 1 add 8 mul 5 add string def
     includecheck {
         /txt barlen 1 add array def
@@ -6072,24 +7075,16 @@
         /txtpos 0 def
     } ifelse
 
-    /checksum 0 def
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /enc encs indx get def               % Get the indxth encoding
-        sbs pos enc putinterval  % Put encoded digit into sbs
+        /indx charvals barcode i 1 getinterval get def
+        sbs pos encs indx get putinterval
         txt i [barcode i 1 getinterval i 12 mul txtpos add textyoffset textfont textsize] put
-        /checksum checksum indx add def
         /pos pos 8 add def
     } for
 
     % Put the checksum
     includecheck {
-        /checksum checksum 35 mod def
         sbs pos encs checksum get putinterval
         includecheckintext {
             txt barlen [barchars checksum 1 getinterval barlen 12 mul txtpos add textyoffset textfont textsize] put
@@ -6126,15 +7121,21 @@
 /bc412 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER bc412--
 
 % --BEGIN ENCODER rationalizedCodabar--
-% --DESC: Rationalized Codabar
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: Codabar
 % --EXAM: A0123456789B
 % --EXOP: includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp rationalizedCodabar 0.0 2014121100 71473 70757
+%%BeginData:        156 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /rationalizedCodabar {
@@ -6145,7 +7146,9 @@
     /barcode exch def          % We are given a barcode string
 
     /dontdraw false def
+    /altstartstop false def
     /includecheck false def     % Enable/disable checkdigit
+    /validatecheck false def
     /includetext false def      % Enable/disable text
     /includecheckintext false def
     /textfont /Courier def
@@ -6178,46 +7181,72 @@
     ] def
 
     % Create a string of the available characters
-    /barchars (0123456789-$:/.+ABCD) def
-
-    /barlen barcode length def    % Length of the code
-
-    includecheck {
-        /sbs barlen 8 mul 8 add string def
-        /txt barlen 1 add array def
+    altstartstop {
+        /barchars (0123456789-$:/.+TN*E) def
     } {
-        /sbs barlen 8 mul string def
-        /txt barlen array def
+        /barchars (0123456789-$:/.+ABCD) def
     } ifelse
+    /charvals 20 dict def
+    0 1 19 {charvals exch dup barchars exch 1 getinterval exch put} for
+    /bodyvals 16 dict def
+    0 1 15 {bodyvals exch dup barchars exch 1 getinterval exch put} for
+    /ssvals 4 dict def
+    16 1 19 {ssvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    barcode 0 1 getinterval ssvals exch known not 
+    barcode barcode length 1 sub 1 getinterval ssvals exch known not or {
+        altstartstop {
+            /bwipp.rationalizedCodabarBadAltStartStop (Codabar start and stop characters must be one of E N T or *) //raiseerror exec
+        } {
+            /bwipp.rationalizedCodabarBadStartStop (Codabar start and stop characters must be one of A B C or D) //raiseerror exec
+        } ifelse
+    } if
+    1 1 barcode length 2 sub {
+        barcode exch 1 getinterval bodyvals exch known not {
+            /bwipp.rationalizedCodabarBadCharacter (Codabar body must contain only digits and symbols - $ : / . +) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
 
     /checksum 0 def
+    0 1 barlen 2 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    barcode barcode length 1 sub 1 getinterval charvals exch get
+    checksum add /checksum exch def 
+    /checksum 16 checksum 16 mod sub 16 mod def
+    validatecheck {
+        barcode barlen 1 sub get barchars checksum get ne {
+            /bwipp.rationalizedCodabarBadCheckDigit (Incorrect Codabar check digit provided) //raiseerror exec
+        } if
+        barlen string
+        dup 0 barcode 0 barlen 1 sub getinterval putinterval
+        dup barlen 1 sub barcode barlen 1 getinterval putinterval
+        /barcode exch def
+        /includecheck true def
+    } if
+
+    /sbs barlen includecheck {1 add} if 8 mul string def
+    /txt barlen includecheck {1 add} if array def
+
     /xpos 0 def
     0 1 barlen 2 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                          % Discard true leaving pre
-        length /indx exch def        % indx is the length of pre
-        pop pop                      % Discard seek and post
-        /enc encs indx get def       % Get the indxth encoding
+        /indx charvals barcode i 1 getinterval get def
+        /enc encs indx get def
         sbs i 8 mul enc putinterval  % Put encoded digit into sbs
         txt i [barcode i 1 getinterval xpos textyoffset textfont textsize] put
         0 1 7 {       % xpos+=width of the character
             /xpos exch enc exch get 48 sub xpos add def
         } for
-        /checksum checksum indx add def
     } for
 
-    % Find index of last character
-    barcode barlen 1 sub 1 getinterval barchars exch search
-    pop                          % Discard true leaving pre
-    length /indx exch def        % indx is the length of pre
-    pop pop                      % Discard seek and post
-
+    % Put the checksum character and stop character
     includecheck {
         % Put the checksum character
-        /checksum checksum indx add def
-        /checksum 16 checksum 16 mod sub 16 mod def
         sbs barlen 8 mul 8 sub encs checksum get putinterval
         includecheckintext {
             txt barlen 1 sub [barchars checksum 1 getinterval xpos textyoffset textfont textsize] put
@@ -6228,11 +7257,13 @@
             /xpos exch encs checksum get exch get 48 sub xpos add def
         } for
         % Put the end character
+        /indx charvals barcode barlen 1 sub 1 getinterval get def
         /enc encs indx get def            % Get the indxth encoding
         sbs barlen 8 mul enc putinterval  % Put encoded digit into sbs
         txt barlen [barcode barlen 1 sub 1 getinterval xpos textyoffset textfont textsize] put
     } {
         % Put the end character
+        /indx charvals barcode barlen 1 sub 1 getinterval get def
         /enc encs indx get def                  % Get the indxth encoding
         sbs barlen 8 mul 8 sub enc putinterval  % Put encoded digit into sbs
         txt barlen 1 sub [barcode barlen 1 sub 1 getinterval xpos textyoffset textfont textsize] put
@@ -6258,15 +7289,21 @@
 /rationalizedCodabar dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER rationalizedCodabar--
 
 % --BEGIN ENCODER onecode--
-% --DESC: United States Postal Service Intelligent Mail
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: USPS Intelligent Mail
 % --EXAM: 0123456709498765432101234567891
 % --EXOP: barcolor=FF0000
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp onecode 0.0 2014121100 105083 104845
+%%BeginData:        335 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /onecode {
@@ -6599,15 +7636,21 @@
 /onecode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER onecode--
 
 % --BEGIN ENCODER postnet--
-% --DESC: United States Postal Service POSTNET
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: USPS POSTNET
 % --EXAM: 01234
 % --EXOP: includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp postnet 0.0 2014121100 67140 66826
+%%BeginData:        140 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /postnet {
@@ -6619,6 +7662,7 @@
 
     /dontdraw false def
     /includetext false def          % Enable/disable text
+    /validatecheck false def
     /includecheckintext false def
     /textfont /Courier def
     /textsize 10 def
@@ -6641,22 +7685,33 @@
     /textyoffset textyoffset cvr def
     /height height cvr def
     
-    /barlen barcode length def
-
-    % Ensure 5, 9 or 11 digits
-    barlen 5 lt {
-        /barlen -1 def  % Error
-    } {
-        barlen 11 ge {
-            /barlen 11 def
-        } if
-        barlen 10 eq {
-            /barlen 9 def
-        } if
-        barlen 8 le {
-            /barlen 5 def
-        } if
-    } ifelse
+    /barlen barcode length validatecheck {1 sub} if def
+
+    % Validate the input
+    barlen 5 ne barlen 9 ne and barlen 11 ne and {
+        /bwipp.postnetBadLength (USPS POSTNET must be 5, 9 or 11 digits excluding check digit) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.postnetBadCharacter (USPS POSTNET must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Create a string of the available characters
+    /barchars (0123456789) def
+
+    /checksum 0 def
+    0 1 barlen 1 sub {
+        /i exch def
+        /checksum checksum barcode i get 48 sub add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.postnetBadCheckDigit (Incorrect USPS POSTNET check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     % Create an array containing the character mappings
     /encs
@@ -6664,9 +7719,6 @@
       (25252) (25522) (52225) (52252) (52522)
       (5) (5)
     ] def
-
-    % Create a string of the available characters
-    /barchars (0123456789) def
 
     /bhs barlen 5 mul 7 add array def
     /txt barlen 1 add array def
@@ -6680,15 +7732,9 @@
     } for
     bhs 0 heights putinterval   % Put encoded digit into sbs
 
-    /checksum 0 def
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                 % Discard true leaving pre
-        length /indx exch def               % indx is the length of pre
-        pop pop                             % Discard seek and post
-        /enc encs indx get def              % Get the indxth encoding
+        /enc encs barcode i get 48 sub get def
         /heights enc length array def
         0 1 enc length 1 sub {
             /j exch def
@@ -6696,11 +7742,9 @@
         } for
         bhs i 5 mul 1 add heights putinterval   % Put encoded digit into sbs
         txt i [barcode i 1 getinterval i 5 mul 1 add 3.312 mul textyoffset textfont textsize] put
-        /checksum checksum indx add def     % checksum+=indx
     } for
 
     % Put the checksum character
-    /checksum 10 checksum 10 mod sub 10 mod def
     /enc encs checksum get def
     /heights enc length array def
     0 1 enc length 1 sub {
@@ -6744,15 +7788,21 @@
 /postnet dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER postnet--
 
 % --BEGIN ENCODER planet--
-% --DESC: United States Postal Service PLANET
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: USPS PLANET
 % --EXAM: 01234567890
 % --EXOP: includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp planet 0.0 2014121100 67000 66690
+%%BeginData:        141 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /planet {
@@ -6764,6 +7814,7 @@
 
     /dontdraw false def
     /includetext false def          % Enable/disable text
+    /validatecheck false def
     /includecheckintext false def
     /textfont /Courier def
     /textsize 10 def
@@ -6785,19 +7836,35 @@
     /textsize textsize cvr def
     /textyoffset textyoffset cvr def
     /height height cvr def
-    
-    /barlen barcode length def
-
-    % Ensure 11 or 13 digits
-    barlen 11 lt {
-        /barlen -1 def  % Error
-    } {
-        barlen 13 ge {
-            /barlen 13 def
-        } {
-            /barlen 11 def
-        } ifelse
-    } ifelse
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    % Validate the input
+    barlen 11 ne barlen 13 ne and {
+        /bwipp.planetBadLength (USPS PLANET must be 11 or 13 digits excluding check digit) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.planetBadCharacter (USPS PLANET must contain only digits) //raiseerror exec
+        } if
+    } forall
+
+    % Create a string of the available characters
+    /barchars (0123456789) def
+
+    % Calculate the checksum
+    /checksum 0 def
+    0 1 barlen 1 sub {
+        /i exch def
+        /checksum checksum barcode i get 48 sub add def
+    } for
+    /checksum 10 checksum 10 mod sub 10 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.planetBadCheckDigit (Incorrect USPS PLANET check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     % Create an array containing the character mappings
     /encs
@@ -6805,9 +7872,6 @@
       (52525) (52255) (25552) (25525) (25255)
       (5) (5)
     ] def
-
-    % Create a string of the available characters
-    /barchars (0123456789) def
 
     /bhs barlen 5 mul 7 add array def
     /txt barlen 1 add array def
@@ -6821,15 +7885,9 @@
     } for
     bhs 0 heights putinterval   % Put encoded digit into sbs
 
-    /checksum 0 def
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                 % Discard true leaving pre
-        length /indx exch def               % indx is the length of pre
-        pop pop                             % Discard seek and post
-        /enc encs indx get def              % Get the indxth encoding
+        /enc encs barcode i get 48 sub get def
         /heights enc length array def
         0 1 enc length 1 sub {
             /j exch def
@@ -6837,11 +7895,9 @@
         } for
         bhs i 5 mul 1 add heights putinterval   % Put encoded digit into sbs
         txt i [barcode i 1 getinterval i 5 mul 1 add 3.312 mul textyoffset textfont textsize] put
-        /checksum checksum indx add def     % checksum+=indx
     } for
 
     % Put the checksum character
-    /checksum 10 checksum 10 mod sub 10 mod def
     /enc encs checksum get def
     /heights enc length array def
     0 1 enc length 1 sub {
@@ -6885,15 +7941,21 @@
 /planet dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER planet--
 
 % --BEGIN ENCODER royalmail--
-% --DESC: Royal Mail 4 State Customer Code (RM4SCC)
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: Royal Mail 4 State Customer Code
 % --EXAM: LE28HS9Z
-% --EXOP: includetext includecheckintext barcolor=FF0000
+% --EXOP: includetext barcolor=FF0000
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp royalmail 0.0 2014121100 67915 67664
+%%BeginData:        145 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /royalmail {
@@ -6905,6 +7967,7 @@
 
     /dontdraw false def
     /includetext false def          % Enable/disable text
+    /validatecheck false def
     /includecheckintext false def
     /textfont /Courier def
     /textsize 10 def
@@ -6926,7 +7989,37 @@
     /textsize textsize cvr def
     /textyoffset textyoffset cvr def
     /height height cvr def
-    
+
+    % Create a string of the available characters
+    /barchars (ZUVWXY501234B6789AHCDEFGNIJKLMTOPQRS) def
+    /charvals 36 dict def
+    0 1 35 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.royalmailBadCharacter (RM4SCC must contain only capital letters and digits) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksumrow 0 def
+    /checksumcol 0 def
+    0 1 barlen 1 sub {
+        /i exch def
+        /indx charvals barcode i 1 getinterval get def
+        /checksumrow checksumrow indx 6 idiv add def
+        /checksumcol checksumcol indx 6 mod add def 
+    } for
+    /checksum checksumrow 6 mod 6 mul checksumcol 6 mod add def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.royalmailBadCheckDigit (Incorrect RM4SCC check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
+
     % Create an array containing the character mappings
     /encs
     [ (3300) (2211) (2301) (2310) (3201) (3210) 
@@ -6938,36 +8031,21 @@
       (2) (3)
     ] def
 
-    % Create a string of the available characters
-    /barchars (ZUVWXY501234B6789AHCDEFGNIJKLMTOPQRS) def
-
-    /barlen barcode length def
     /encstr barlen 4 mul 6 add string def
     /txt barlen 1 add array def
 
     % Put start character
     encstr 0 encs 36 get putinterval
     
-    /checksumrow 0 def
-    /checksumcol 0 def
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                 % Discard true leaving pre
-        length /indx exch def               % indx is the length of pre
-        pop pop                             % Discard seek and post
-        /enc encs indx get def              % Get the indxth encoding
-        encstr i 4 mul 1 add enc putinterval
+        /indx charvals barcode i 1 getinterval get def
+        encstr i 4 mul 1 add encs indx get putinterval
         txt i [barcode i 1 getinterval i 4 mul 1 add 3.312 mul textyoffset textfont textsize] put
-        /checksumrow checksumrow indx 6 idiv add def
-        /checksumcol checksumcol indx 6 mod add def 
     } for
 
     % Put the checksum character
-    /checksum checksumrow 6 mod 6 mul checksumcol 6 mod add def
-    /enc encs checksum get def
-    encstr barlen 4 mul 1 add enc putinterval
+    encstr barlen 4 mul 1 add encs checksum get putinterval
     includecheckintext {
         txt barlen [barchars checksum 1 getinterval barlen 4 mul 1 add 3.312 mul textyoffset textfont textsize] put
     } {
@@ -7020,15 +8098,21 @@
 /royalmail dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER royalmail--
 
 % --BEGIN ENCODER auspost--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: AusPost 4 State Customer Code
 % --EXAM: 5956439111ABA 9
 % --EXOP: includetext custinfoenc=character
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp auspost 0.0 2014121100 78727 78454
+%%BeginData:        202 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /auspost {
@@ -7228,15 +8312,21 @@
 /auspost dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER auspost--
 
 % --BEGIN ENCODER kix--
-% --DESC: Royal Dutch TPG Post KIX 4-State Barcode
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: Royal Dutch TPG Post KIX
 % --EXAM: 1231FZ13XHS
-% --EXOP: includetext includecheckintext
+% --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp kix 0.0 2014121100 63057 62851
+%%BeginData:        111 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /kix {
@@ -7248,7 +8338,6 @@
 
     /dontdraw false def
     /includetext false def          % Enable/disable text
-    /includecheckintext false def
     /textfont /Courier def
     /textsize 10 def
     /textyoffset -7 def
@@ -7282,6 +8371,15 @@
 
     % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) def
+    /charvals 36 dict def
+    0 1 35 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.kixBadCharacter (KIX must contain only capital letters and digits) //raiseerror exec
+        } if
+    } for
 
     /barlen barcode length def
     /encstr barlen 4 mul string def
@@ -7289,13 +8387,8 @@
     
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                 % Discard true leaving pre
-        length /indx exch def               % indx is the length of pre
-        pop pop                             % Discard seek and post
-        /enc encs indx get def              % Get the indxth encoding
-        encstr i 4 mul enc putinterval
+        /indx charvals barcode i 1 getinterval get def
+        encstr i 4 mul encs indx get putinterval
         txt i [barcode i 1 getinterval i 4 mul 3.312 mul textyoffset textfont textsize] put
     } for
 
@@ -7342,15 +8435,21 @@
 /kix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER kix--
 
 % --BEGIN ENCODER japanpost--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Japan Post 4 State Customer Code
 % --EXAM: 6540123789-A-K-Z
 % --EXOP: includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp japanpost 0.0 2014121100 68076 67796
+%%BeginData:        162 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /japanpost {
@@ -7510,15 +8609,21 @@
 /japanpost dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER japanpost--
 
 % --BEGIN ENCODER msi--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: MSI Modified Plessey
 % --EXAM: 0123456789
 % --EXOP: includetext includecheck includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp msi 0.0 2014121100 73223 72733
+%%BeginData:        139 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /msi {
@@ -7655,15 +8760,21 @@
 /msi dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER msi--
 
 % --BEGIN ENCODER plessey--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Plessey UK
 % --EXAM: 01234ABCD
 % --EXOP: includetext includecheckintext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp plessey 0.0 2014121100 69717 69236
+%%BeginData:        146 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /plessey {
@@ -7675,6 +8786,7 @@
 
     /dontdraw false def
     /includetext false def    % Enable/disable text
+    /validatecheck false def
     /includecheckintext false def
     /unidirectional false def
     /textfont /Courier def
@@ -7698,6 +8810,58 @@
     /textyoffset textyoffset cvr def
     /height height cvr def
     
+    % Create a string of the available characters
+    /barchars (0123456789ABCDEF) def
+    /charvals 16 dict def
+    0 1 15 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.plesseyBadCharacter (Plessey must contain only digits and letters A B C D E F) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {2 sub} if def
+
+    % Calculate the checksums
+    /checkbits barlen 4 mul 8 add array def
+    checkbits barlen 4 mul [ 0 0 0 0 0 0 0 0 ] putinterval
+    0 1 barlen 1 sub {
+        /i exch def
+        /indx charvals barcode i 1 getinterval get def
+        checkbits i 4 mul [
+                indx 1 and
+                indx -1 bitshift 1 and
+                indx -2 bitshift 1 and
+                indx -3 bitshift
+        ] putinterval
+    } for
+    /checksalt [ 1 1 1 1 0 1 0 0 1 ] def
+    0 1 barlen 4 mul 1 sub {
+        /i exch def
+        checkbits i get 1 eq {
+            0 1 8 {
+                /j exch def
+                checkbits i j add checkbits i j add get checksalt j get xor put
+            } for
+        } if
+    } for
+    /checkval 0 def
+    0 1 7 {
+        /i exch def
+        /checkval checkval 2 i exp cvi checkbits barlen 4 mul i add get mul add def
+    } for
+    /checksum1 checkval 15 and def
+    /checksum2 checkval -4 bitshift def
+    validatecheck {
+        barcode barlen get barchars checksum1 get ne
+        barcode barlen 1 add get barchars checksum2 get ne or {
+            /bwipp.plesseyBadCheckDigits (Incorrect Plessey check digits provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
+
     % Create an array containing the character mappings
     /encs
     [ (14141414) (32141414) (14321414) (32321414)
@@ -7707,62 +8871,20 @@
       (32321432) (541412323) (323)
     ] def
 
-    % Create a string of the available characters
-    /barchars (0123456789ABCDEF) def
-
-    /barlen barcode length def     % Length of the code
-    unidirectional {
-        /sbs barlen 8 mul 27 add string def
-    } {
-        /sbs barlen 8 mul 33 add string def
-    } ifelse
+    /sbs barlen 8 mul unidirectional {27} {33} ifelse add string def
     /txt barlen 2 add array def
-    /checkbits barlen 4 mul 8 add array def
-    checkbits barlen 4 mul [ 0 0 0 0 0 0 0 0 ] putinterval
 
     % Put start character
     sbs 0 encs 16 get putinterval
 
     0 1 barlen 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                % Discard true leaving pre
-        length /indx exch def              % indx is the length of pre
-        pop pop                            % Discard seek and post
-        /enc encs indx get def             % Get the indxth encoding
-        sbs i 8 mul 8 add enc putinterval  % Put encoded digit into sbs
+        /indx charvals barcode i 1 getinterval get def
+        sbs i 8 mul 8 add encs indx get putinterval
         txt i [barcode i 1 getinterval i 20 mul 20 add textyoffset textfont textsize] put
-        checkbits i 4 mul [
-                indx 1 and
-                indx -1 bitshift 1 and
-                indx -2 bitshift 1 and
-                indx -3 bitshift
-        ] putinterval
     } for
 
-    % Checksum is last 8 bits of a CRC using a salt
-    /checksalt [ 1 1 1 1 0 1 0 0 1 ] def
-    0 1 barlen 4 mul 1 sub {
-        /i exch def
-        checkbits i get 1 eq {
-            0 1 8 {
-                /j exch def
-                checkbits i j add checkbits i j add get checksalt j get xor put
-            } for
-        } if
-    } for
-
-    % Calculate the value of the checksum digits
-    /checkval 0 def
-    0 1 7 {
-        /i exch def
-        /checkval checkval 2 i exp cvi checkbits barlen 4 mul i add get mul add def
-    } for
-
     % Put the checksum characters
-    /checksum1 checkval 15 and def
-    /checksum2 checkval -4 bitshift def
     sbs barlen 8 mul 8 add encs checksum1 get putinterval
     sbs barlen 8 mul 16 add encs checksum2 get putinterval
     includecheckintext {
@@ -7774,11 +8896,7 @@
     } ifelse
 
     % Put end character
-    unidirectional {
-        sbs barlen 8 mul 24 add encs 18 get putinterval
-    } {
-        sbs barlen 8 mul 24 add encs 17 get putinterval
-    } ifelse
+    sbs barlen 8 mul 24 add encs unidirectional {18} {17} ifelse get putinterval
 
     % Return the arguments
     <<
@@ -7800,15 +8918,21 @@
 /plessey dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER plessey--
 
 % --BEGIN ENCODER telepen--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Telepen
 % --EXAM: 123456
 % --EXOP: numeric includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp telepen 0.0 2014121100 71123 70715
+%%BeginData:        173 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /telepen {
@@ -7979,15 +9103,21 @@
 /telepen dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER telepen--
 
 % --BEGIN ENCODER posicode--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: PosiCode
 % --EXAM: ABC123
 % --EXOP: version=b inkspread=-0.5 parsefnc includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp posicode 0.0 2014121100 109732 109034
+%%BeginData:        389 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /posicode {
@@ -8374,15 +9504,21 @@
 /posicode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER posicode--
 
 % --BEGIN ENCODER codablockf--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Codablock F
 % --EXAM: CODABLOCK F 34567890123456789010040digit
 % --EXOP: columns=8
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp codablockf 0.0 2014121100 136007 135295
+%%BeginData:        512 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /codablockf {
@@ -8892,15 +10028,21 @@
 /codablockf dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER codablockf--
 
 % --BEGIN ENCODER code16k--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Code 16K
 % --EXAM: Abcd-1234567890-wxyZ
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp code16k 0.0 2014121100 156180 158943
+%%BeginData:        710 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /code16k {
@@ -9608,15 +10750,21 @@
 /code16k dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code16k--
 
 % --BEGIN ENCODER code49--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Code 49
 % --EXAM: MULTIPLE ROWS IN CODE 49
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp code49 0.0 2014121100 264067 280283
+%%BeginData:       1076 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /code49 {
@@ -10690,15 +11838,21 @@
 /code49 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER code49--
 
 % --BEGIN ENCODER channelcode--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Channel Code
 % --EXAM: 3493
 % --EXOP: height=0.5 includetext 
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp channelcode 0.0 2014121100 70263 69772
+%%BeginData:        149 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /channelcode {
@@ -10726,19 +11880,19 @@
     options {def} forall
 
     /height height cvr def
-  
-    /barlen barcode length def
-
-    barlen 2 ge barlen 7 le and {
-        /channels barlen 1 add def
-    } if
-
-    % Determine finder
-    shortfinder {
-        /finder [ 1 1 1 1 1 ] def
-    } {
-        /finder [ 1 1 1 1 1 1 1 1 1 ] def
-    } ifelse
+
+    % Validate the input
+    barcode length 2 lt barcode length 7 gt or {
+        /bwipp.channelcodeBadLength (Channel Code must be 2 to 7 digits) //raiseerror exec
+    } if
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.channelcodeBadCharacter (Channel Code must contain only digits) //raiseerror exec
+        } if
+    } forall
+    barcode cvi [ 26 292 3493 44072 576688 7742862 ] barcode length 2 sub get gt {
+        /bwipp.channelcodeTooBig (The Channel Code value is too big for the number of channels) //raiseerror exec
+    } if
 
     /nextb {
         dup
@@ -10785,21 +11939,26 @@
         out
     } bind def
 
+    /barlen barcode length def
+
+    % Determine finder
+    /finder shortfinder { [ 1 1 1 1 1 ] } { [ 1 1 1 1 1 1 1 1 1 ] } ifelse def
+
     % Encode the main data
-    /data barcode cvi channels encode def
+    /data barcode cvi barlen 1 add encode def
 
     % Determine check data
     /check [] def
     includecheck {
         /mod23 [
-            [] [] []
+            [] []
             [ 13 12  4  9  3  1 ]
             [ 13  2 12  3 18 16  4  1 ]
             [ 11 16 17  8 20  4 10  2  5  1 ]
             [  1  4 16 18  3 12  2  8  9 13  6  1 ]
             [ 20 16 22 13 15 12  5  4  8  9 21  3  7  1 ]
             [  2  6 18  8  1  3  9  4 12 13 16  2  6 18  8  1 ]
-        ] channels get def
+        ] barlen get def
         0
         0 1 data length 1 sub {
             dup data exch get 1 sub exch mod23 exch get mul add
@@ -10840,15 +11999,21 @@
 /channelcode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER channelcode--
 
 % --BEGIN ENCODER flattermarken--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Flattermarken
-% --EXAM: 12345
-% --EXOP: inkspread=-0.25
+% --EXAM: 11099
+% --EXOP: inkspread=-0.25 showborder borderleft=0 borderright=0
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp flattermarken 0.0 2014121100 59859 59559
+%%BeginData:         93 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /flattermarken {
@@ -10864,6 +12029,13 @@
     /textsize 10 def
     /textyoffset -7 def
     /height 0.3 def
+
+    % Validate the input
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.flattermarkenBadCharacter (Flattermarken must contain only digits) //raiseerror exec
+        } if
+    } forall
 
     % Parse the input options
     options type /stringtype eq {
@@ -10880,6 +12052,13 @@
     /textsize textsize cvr def
     /textyoffset textyoffset cvr def
     /height height cvr def
+
+    % Validate the input
+    barcode {
+        dup 48 lt exch 57 gt or {
+            /bwipp.flattermarkenBadCharacter (Flattermarken must contain only digits) //raiseerror exec
+        } if
+    } forall
 
     % Create an array containing the character mappings
     /encs
@@ -10925,15 +12104,21 @@
 /flattermarken dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER flattermarken--
 
 % --BEGIN ENCODER raw--
-% --DESC: Raw bar space succession for custom symbologies 
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: Custom 1D symbology
 % --EXAM: 331132131313411122131311333213114131131221323
 % --EXOP: height=0.5
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp raw 0.0 2014121100 55669 55558
+%%BeginData:         52 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /raw {
@@ -10941,7 +12126,7 @@
     20 dict begin                  % Confine variables to local scope
 
     /options exch def        % We are given an option string
-    /sbs exch def        % We are given a barcode string
+    /barcode exch def        % We are given a barcode string
 
     /dontdraw false def
     /height 1 def
@@ -10959,12 +12144,19 @@
 
     /height height cvr def
 
+    % Validate input
+    barcode {
+        dup 49 lt exch 57 gt or {
+            /bwipp.rawBadCharacter (Raw must contain only digits 1 to 9) //raiseerror exec
+        } if
+    } forall
+
     % Return the arguments
     <<
     /ren //renlinear
-    /sbs [sbs {48 sub} forall]
-    /bhs [sbs length 1 add 2 idiv {height} repeat]
-    /bbs [sbs length 1 add 2 idiv {0} repeat]
+    /sbs [barcode {48 sub} forall]
+    /bhs [barcode length 1 add 2 idiv {height} repeat]
+    /bbs [barcode length 1 add 2 idiv {0} repeat]
     /opt options
     >>
 
@@ -10976,15 +12168,21 @@
 /raw dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER raw--
 
 % --BEGIN ENCODER daft--
-% --DESC: Raw DAFT succession for custom 4 state symbologies
+% --REQUIRES preamble raiseerror renlinear--
+% --DESC: Custom 4 state symbology
 % --EXAM: FATDAFTDAD
 % --EXOP:
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp daft 0.0 2014121100 58923 58681
+%%BeginData:         76 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /daft {
@@ -11010,6 +12208,12 @@
 
     /height height cvr def
 
+    barcode {
+        dup 68 ne exch dup 65 ne exch dup 70 ne exch 84 ne and and and {
+            /bwipp.daftBadCharacter (DAFT must contain only characters D, A, F and T) //raiseerror exec
+        } if
+    } forall
+
     /barlen barcode length def
 
     /bbs barlen array def
@@ -11052,15 +12256,21 @@
 /daft dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER daft--
 
 % --BEGIN ENCODER symbol--
+% --REQUIRES preamble raiseerror renlinear--
 % --DESC: Miscellaneous symbols
 % --EXAM: fima
 % --EXOP: backgroundcolor=DD000011
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp symbol 0.0 2014121100 58527 58256
+%%BeginData:         72 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
 begin
 /symbol {
@@ -11083,30 +12293,36 @@
     } if
     options {def} forall
 
-    barcode (fima) eq {
-        /sbs [2.25 2.25 2.25 11.25 2.25 11.25 2.25 2.25 2.25] def
-        /bhs [.625 .625 .625 .625 .625] def
-        /bbs [0 0 0 0 0] def
-    } if
-
-    barcode (fimb) eq {
-        /sbs [2.25 6.75 2.25 2.25 2.25 6.25 2.25 2.25 2.25 6.75 2.25] def
-        /bhs [.625 .625 .625 .625 .625 .625] def
-        /bbs [0 0 0 0 0 0] def
-    } if
-
-    barcode (fimc) eq {
-        /sbs [2.25 2.25 2.25 6.75 2.25 6.75 2.25 6.75 2.25 2.25 2.25] def
-        /bhs [.625 .625 .625 .625 .625 .625] def
-        /bbs [0 0 0 0 0 0] def
-    } if
-    
-    barcode (fimd) eq {
-        /sbs [2.25 2.25 2.25 2.25 2.25 6.75 2.25 6.75 2.25 2.25 2.25 2.25 2.25] def
-        /bhs [.625 .625 .625 .625 .625 .625 .625] def
-        /bbs [0 0 0 0 0 0 0] def
-    } if
-    
+    /symbols <<
+        /fima {
+            /sbs [2.25 2.25 2.25 11.25 2.25 11.25 2.25 2.25 2.25] def
+            /bhs [.625 .625 .625 .625 .625] def
+            /bbs [0 0 0 0 0] def
+        } bind
+        /fimb {
+            /sbs [2.25 6.75 2.25 2.25 2.25 6.25 2.25 2.25 2.25 6.75 2.25] def
+            /bhs [.625 .625 .625 .625 .625 .625] def
+            /bbs [0 0 0 0 0 0] def
+        } bind
+        /fimc {
+            /sbs [2.25 2.25 2.25 6.75 2.25 6.75 2.25 6.75 2.25 2.25 2.25] def
+            /bhs [.625 .625 .625 .625 .625 .625] def
+            /bbs [0 0 0 0 0 0] def
+        } bind
+        /fimd {
+            /sbs [2.25 2.25 2.25 2.25 2.25 6.75 2.25 6.75 2.25 2.25 2.25 2.25 2.25] def
+            /bhs [.625 .625 .625 .625 .625 .625 .625] def
+            /bbs [0 0 0 0 0 0 0] def
+        } bind
+    >> def
+
+    % Valiate input   
+    symbols barcode known not {
+        /bwipp.symbolUnknownSymbol (Unknown symbol name provided) //raiseerror exec 
+    } if
+
+    symbols barcode get exec
+ 
     % Return the arguments
     <<
     /ren //renlinear
@@ -11124,15 +12340,21 @@
 /symbol dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER symbol--
 
 % --BEGIN ENCODER pdf417--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: PDF417
 % --EXAM: This is PDF417
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp pdf417 0.0 2014121100 196239 198381
+%%BeginData:        873 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /pdf417 {
@@ -11148,6 +12370,7 @@
     /columns 0 def
     /rows 0 def
     /rowmult 3 def
+    /encoding (auto) def
     /ccc false def
     /raw false def
     /parse false def
@@ -11189,8 +12412,10 @@
         } loop
     } if
 
+    raw {/encoding (raw) def} if
+
     % Convert input into array of codewords
-    raw {
+    encoding (raw) eq {
         /datcws barcode length array def
         /i 0 def /j 0 def
         { % loop
@@ -11201,54 +12426,419 @@
             /j j 1 add def
         } loop
         /datcws datcws 0 j getinterval def
-    } {  % Simple autoencoder from input to codewords using byte mode
-        /barlen barcode length def
-        barlen 6 mod 0 eq {
-            /datcws barlen 6 idiv 5 mul 1 add array def
-            datcws 0 924 put
-        } {
-            /datcws barlen 6 idiv 5 mul barlen 6 mod add 1 add array def
-            datcws 0 901 put 
-        } ifelse
-
-        % Rebase groups of 6 bytes splitting into 3 byte chunks
-        0 1 barlen 6 idiv 1 sub {
-            /i exch def
-            /msbs [ barcode i 6 mul 3 getinterval {} forall ] def
+    } if
+
+    /barcode [ barcode {} forall ] def
+    /barlen barcode length def
+
+    ccc {/encoding (ccc) def} if
+
+    /encb {
+        /in exch def
+        /inlen in length def
+        /out inlen 6 idiv 5 mul inlen 6 mod add array def
+        0 1 inlen 6 idiv 1 sub {
+            /k exch def
+            /msbs [ in k 6 mul 3 getinterval aload pop ] def
             /mscs [
-                msbs aload pop exch 256 mul add exch 65536 mul add 
-                3 {dup 900 mod exch 900 idiv} repeat 
+                msbs aload pop exch 256 mul add exch 65536 mul add
+                3 {dup 900 mod exch 900 idiv} repeat
             ] def
-            /lsbs [barcode i 6 mul 3 add 3 getinterval {} forall] def
+            /lsbs [ in k 6 mul 3 add 3 getinterval aload pop ] def
             /lscs [
                 lsbs aload pop exch 256 mul add exch 65536 mul add
                 3 {dup 900 mod exch 900 idiv} repeat
             ] def
-            /cws 5 array def
             lscs 0 get mscs 0 get 316 mul add
-            cws 4 2 index 900 mod put
+            out k 5 mul 4 add 2 index 900 mod put
             900 idiv lscs 1 get add mscs 0 get 641 mul add mscs 1 get 316 mul add
-            cws 3 2 index 900 mod put 
-            900 idiv lscs 2 get add mscs 0 get 20 mul add mscs 1 get 641 mul add mscs 2 get 316 mul add 
-            cws 2 2 index 900 mod put
+            out k 5 mul 3 add 2 index 900 mod put
+            900 idiv lscs 2 get add mscs 0 get 20 mul add mscs 1 get 641 mul add mscs 2 get 316 mul add
+            out k 5 mul 2 add 2 index 900 mod put
             900 idiv lscs 3 get add mscs 1 get 20 mul add mscs 2 get 641 mul add
-            cws 1 2 index 900 mod put
+            out k 5 mul 1 add 2 index 900 mod put
             900 idiv mscs 2 get 20 mul add
-            cws 0 3 -1 roll 900 mod put
-            datcws i 5 mul 1 add cws putinterval 
+            out k 5 mul 3 -1 roll 900 mod put
         } for
-
-        % Add the remaining bytes to the end of the codewords
-        /rem barlen 6 mod def
+        /rem inlen 6 mod def
         rem 0 ne {
-            datcws datcws length rem sub 
-            [ barcode barlen rem sub rem getinterval {} forall ] 
+            out out length rem sub
+            [ in inlen rem sub rem getinterval aload pop ]
             putinterval
         } if
-
-        ccc {/datcws [920 datcws aload pop] def} if
-
-    } ifelse
+        out
+    } bind def
+    
+    encoding (byte) eq encoding (ccc) eq or {
+        /datcws barlen 6 idiv 5 mul barlen 6 mod add 1 add array def
+        datcws 0 barlen 6 mod 0 eq {924} {901} ifelse put
+        datcws 1 barcode encb putinterval
+        encoding (ccc) eq {/datcws [920 datcws aload pop] def} if
+    } if
+
+    encoding (auto) eq {
+
+        % Modes and text submodes
+        /T 0 def  /N 1 def  /B 2 def
+        /A 0 def  /L 1 def  /M 2 def  /P 3 def
+        
+        % Special function characters for mode switching
+        /tl -1 def  /nl -2 def  /bl -3 def  /bl6 -4 def  /bs -5 def
+        
+        % Special function characters for text mode
+        /al -6 def  /ll -7 def  /ml -8 def  /pl -9 def  /as -10 def  /ps -11 def
+        
+        % Character maps for each state
+        /charmaps [
+          %  A    L    M    P
+          [ (A)  (a)  (0)  (;) ]  % 0
+          [ (B)  (b)  (1)  (<) ]  % 1
+          [ (C)  (c)  (2)  (>) ]  % 2
+          [ (D)  (d)  (3)  (@) ]  % 3
+          [ (E)  (e)  (4)  ([) ]  % 4
+          [ (F)  (f)  (5)   92 ]  % 5
+          [ (G)  (g)  (6)  (]) ]  % 6
+          [ (H)  (h)  (7)  (_) ]  % 7
+          [ (I)  (i)  (8)  (`) ]  % 8
+          [ (J)  (j)  (9)  (~) ]  % 9
+          [ (K)  (k)  (&)  (!) ]  % 10
+          [ (L)  (l)   13   13 ]  % 11
+          [ (M)  (m)    9    9 ]  % 12
+          [ (N)  (n)  (,)  (,) ]  % 13
+          [ (O)  (o)  (:)  (:) ]  % 14
+          [ (P)  (p)  (#)   10 ]  % 15
+          [ (Q)  (q)  (-)  (-) ]  % 16
+          [ (R)  (r)  (.)  (.) ]  % 17
+          [ (S)  (s)  ($)  ($) ]  % 18
+          [ (T)  (t)  (/)  (/) ]  % 19
+          [ (U)  (u)  (+)  (") ]  % 20
+          [ (V)  (v)  (%)  (|) ]  % 21
+          [ (W)  (w)  (*)  (*) ]  % 22
+          [ (X)  (x)  (=)   40 ]  % 23
+          [ (Y)  (y)  (^)   41 ]  % 24
+          [ (Z)  (z)   pl  (?) ]  % 25
+          [ ( )  ( )  ( )  ({) ]  % 26
+          [  ll   as   ll  (}) ]  % 27
+          [  ml   ml   al  (') ]  % 28
+          [  ps   ps   ps   al ]  % 29
+        ] def
+        
+        % Invert charmaps to give character to value maps for each state
+        /charvals [ 30 dict 30 dict 30 dict 30 dict ] def
+        /alltext 104 dict def
+        0 1 charmaps length 1 sub {
+          /i exch def
+          /encs charmaps i get def
+          0 1 3 {
+            /j exch def
+            encs j get dup type /stringtype eq {0 get} if  % convert string to ASCII if required
+            dup charvals j get exch i put
+            alltext exch -1 put
+          } for
+        } for
+        
+        /e 10000 def  % "Empty"
+        
+        /latlen [  % Bit length of latch between submodes
+        % To:  A  L  M  P      From
+            [  0  1  1  2 ]  % A
+            [  2  0  1  2 ]  % L
+            [  1  1  0  1 ]  % M
+            [  1  2  2  0 ]  % P
+        ] def
+        
+        /latseq [  % Latch sequences between submodes
+        % To: A       L       M       P               From
+            [ []      [ll]    [ml]    [ml pl]    ]  % A
+            [ [ml al] []      [ml]    [ml pl]    ]  % L
+            [ [al]    [ll]    []      [pl]       ]  % M
+            [ [al]    [al ll] [al ml] []         ]  % P
+        ] def
+        
+        /shftlen [  % Bit length of shift to submode
+        % To:  A  L  M  P      From
+            [  e  e  e  1 ]  % A
+            [  1  e  e  1 ]  % L
+            [  e  e  e  1 ]  % M
+            [  e  e  e  e ]  % P
+        ] def
+        
+        % Determine runlengths of digits
+        /numdigits [ barlen {0} repeat 0 ] def
+        /numtext   [ barlen {0} repeat 0 ] def
+        /numbytes  [ barlen {0} repeat 0 ] def
+        barlen 1 sub -1 0 {
+            /i exch def
+            barcode i get dup 48 ge exch 57 le and {
+                numdigits i numdigits i 1 add get 1 add put
+            } if
+            alltext barcode i get known numdigits i get 13 lt and {
+                numtext i numtext i 1 add get 1 add put
+            } if
+            numtext i get 5 lt numdigits i get 13 lt and {
+                numbytes i numbytes i 1 add get 1 add put
+            } if
+        } for
+        /numdigits numdigits 0 barlen getinterval def
+        /numtext   numtext   0 barlen getinterval def
+        /numbytes  numbytes  0 barlen getinterval def
+        
+        /seq [] def /seqlen 0 def /state T def /p 0 def {  % loop
+            p barlen eq {exit} if
+            /n numdigits p get def
+            n 13 ge {
+                /seq [
+                    seq aload pop
+                    nl
+                    [ barcode p n getinterval aload pop ]
+                ] def
+                /state N def
+                /p p n add def
+                /seqlen seqlen 1 add n add def
+            } {  % next
+            /t numtext p get def
+            t 5 ge {
+                /seq [
+                    seq aload pop
+                    state T ne {tl} if
+                    [ barcode p t getinterval aload pop ]
+                ] def
+                /state T def
+                /p p t add def
+                /seqlen seqlen 1 add t add def  % ish
+            } {  % next
+            /b numbytes p get def
+            b 1 eq state T eq and {
+                /seq [
+                    seq aload pop
+                    bs
+                    [ barcode p get ]
+                ] def
+                /p p b add def
+                /seqlen seqlen 2 add def
+            } {  % next
+                /seq [
+                    seq aload pop
+                    b 6 mod 0 ne {bl} {bl6} ifelse
+                    [ barcode p b getinterval aload pop ]
+                ] def
+                /state B def
+                /p p b add def
+                /seqlen seqlen 1 add b add def
+            } ifelse } ifelse } ifelse
+        } loop
+        
+        /latchcws <<
+            tl 900  bl 901  bl6 924  nl 902  bs 913
+        >> def
+        
+        % Submode encoding functions
+        /enca {charvals A get exch get} bind def
+        /encl {charvals L get exch get} bind def
+        /encm {charvals M get exch get} bind def
+        /encp {charvals P get exch get} bind def
+        /textencfuncs [ /enca /encl /encm /encp ] def
+        
+        /addtotext {
+            text exch l exch put
+            /l l 1 add def
+        } bind def
+        
+        /enct {
+        
+            /in exch def
+        
+            /curlen [  e  e  e  e ] def
+            curlen submode 0 put
+            /curseq [ [] [] [] [] ] def
+        
+            % Derive the optimal sequences ending in each submode
+            in {
+        
+                /char exch def
+        
+                % Check for optimisations in the current sequences by latching from x to y
+                {  % loop
+                    /imp false def
+                    [ A L M P ] {
+                        /x exch def
+                        [ A L M P ] {
+                            /y exch def
+                            /cost curlen x get latlen x get y get add def
+                            cost curlen y get lt {
+                                curlen y cost put
+                                curseq y [
+                                    curseq x get aload pop
+                                    latseq x get y get aload pop
+                                ] put
+                                /imp true def
+                            } if
+                        } forall
+                    } forall
+                    imp not {exit} if  % Repeat unless no improvement
+                } loop
+        
+                % Determine optimal next sequences for each valid encoding
+                /nxtlen [ e e e e ] def
+                /nxtseq 4 array def
+        
+                [ A L M P ] {
+                    /x exch def
+        
+                    { % loop for common exit
+        
+                        charvals x get char known not {exit} if
+        
+                        % Extend directly
+                        /cost curlen x get 1 add def
+                        cost nxtlen x get lt {
+                            nxtlen x cost put
+                            nxtseq x [ curseq x get aload pop char ] put
+                        } if
+        
+                        % Optimise for direct shifts from y to x
+                        [ A L M P ] {
+                            /y exch def
+                            x y ne {
+                                /cost curlen y get shftlen y get x get add 1 add def
+                                cost nxtlen y get lt {
+                                    nxtlen y cost put
+                                    nxtseq y [
+                                        curseq y get aload pop
+                                        x A eq {as} {ps} ifelse
+                                        char
+                                    ] put
+                                } if
+                            } if
+                        } forall
+        
+                        exit
+                    } loop
+        
+                } forall
+        
+                /curlen nxtlen def
+                /curseq nxtseq def
+        
+            } forall
+        
+            % Select the optimal sequence
+            /minseq e def
+            [ A L M P ] {
+                /k exch def
+                curlen k get minseq lt {
+                    /minseq curlen k get def
+                    /txtseq curseq k get def
+                } if
+            } forall
+        
+            % Encode the sequence
+            /text minseq array def
+            /k 0 def /l 0 def {
+                k txtseq length ge {exit} if
+        
+                /char txtseq k get def
+        
+                % Encode character
+                char textencfuncs submode get load exec addtotext
+                /k k 1 add def
+        
+                % Encode shifted next character
+                char as eq char ps eq or {
+                    txtseq k get char as eq {enca} {encp} ifelse addtotext
+                    /k k 1 add def
+                } if
+        
+                % Latches to new submode
+                char al eq {/submode A def} if
+                char ll eq {/submode L def} if
+                char ml eq {/submode M def} if
+                char pl eq {/submode P def} if
+            } loop
+        
+            text length 2 mod 1 eq {
+                submode P eq {
+                    /pad al encp def
+                    /submode A def
+                } {
+                    /pad ps textencfuncs submode get load exec def
+                } ifelse
+                /text [ text aload pop pad ] def
+            } if
+        
+            /out text length 2 idiv array def
+            0 1 out length 1 sub {
+                /k exch def
+                out k text k 2 mul get 30 mul text k 2 mul 1 add get add put
+            } for
+        
+            out
+        
+        } bind def
+        
+        /encn {
+            /in exch def
+            /out [] def
+            0 44 in length 1 sub {
+                /k exch def
+                /gmod [
+                    1 in k in length k sub dup 44 gt {pop 44} if getinterval
+                    {48 sub} forall
+                ] def
+                /cwn [] def {
+                    /dv 900 def
+                    /gmul [] def /val 0 def {
+                        gmod length 0 eq {exit} if
+                        /val val 10 mul gmod 0 get add def
+                        /gmod gmod 1 gmod length 1 sub getinterval def
+                        val dv lt {
+                            gmul length 0 ne {
+                                /gmul [ gmul aload pop 0 ] def
+                            } if
+                        } {
+                            /gmul [ gmul aload pop val dv idiv ] def
+                        } ifelse
+                        /val val dv mod def
+                    } loop
+                    /dv val def
+                    /cwn [ dv cwn aload pop ] def
+                    /gmod gmul def
+                    gmul length 0 eq {exit} if
+                } loop
+                /out [ out aload pop cwn aload pop ] def
+            } for
+            out
+        } bind def
+       
+        /encfuncs [ /enct /encn /encb ] def
+        
+        /addtocws {
+            dup datcws j 3 -1 roll putinterval
+            length j add /j exch def
+        } bind def
+        
+        % Encode the sequence
+        /state T def /submode A def
+        /datcws seqlen array def
+        /i 0 def /j 0 def {
+            i seq length ge {exit} if
+            /chars seq i get def
+            chars type /arraytype eq {  % Encode data according to mode
+                chars encfuncs state get load exec addtocws
+            } {  % Encode the latch to new state or byte shift
+                [ latchcws chars get ] addtocws
+                chars tl eq {/state T def /submode A def} if
+                chars nl eq {/state N def} if
+                chars bl eq chars bl6 eq or {/state B def} if
+                chars bs eq {
+                    /i i 1 add def
+                    seq i get encb addtocws
+                } if
+            } ifelse
+            /i i 1 add def
+        } loop
+        /datcws datcws 0 j getinterval def
+    } if
 
     % Determine the error correction level if unspecified
     /m datcws length def
@@ -11635,15 +13225,21 @@
 /pdf417 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER pdf417--
 
 % --BEGIN ENCODER micropdf417--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: MicroPDF417
 % --EXAM: MicroPDF417
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp micropdf417 0.0 2014121100 206374 212034
+%%BeginData:        952 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /micropdf417 {
@@ -11657,6 +13253,7 @@
     /columns 0 def
     /rows 0 def
     /rowmult 2 def
+    /encoding (auto) def
     /cca false def
     /ccb false def
     /raw false def
@@ -11676,8 +13273,6 @@
     /columns columns cvi def
     /rows rows cvi def
     /rowmult rowmult cvr def
-
-    cca {/raw true def} if
 
     % Parse ordinals of the form ^NNN to ASCII
     parse {
@@ -11700,8 +13295,11 @@
         } loop
     } if
 
+    raw {/encoding (raw) def} if
+    cca {/encoding (cca) def} if
+
     % Convert input into array of codewords
-    raw {
+    encoding (raw) eq encoding (cca) eq or {
         /datcws barcode length array def
         /i 0 def /j 0 def
         { % loop
@@ -11712,54 +13310,419 @@
             /j j 1 add def
         } loop
         /datcws datcws 0 j getinterval def
-    } {  % Simple autoencoder from input to codewords using byte mode
-        /barlen barcode length def
-        barlen 6 mod 0 eq {
-            /datcws barlen 6 idiv 5 mul 1 add array def
-            datcws 0 924 put
-        } {
-            /datcws barlen 6 idiv 5 mul barlen 6 mod add 1 add array def
-            datcws 0 901 put 
-        } ifelse
-
-        % Rebase groups of 6 bytes splitting into 3 byte chunks
-        0 1 barlen 6 idiv 1 sub {
-            /i exch def
-            /msbs [ barcode i 6 mul 3 getinterval {} forall ] def
+    } if
+
+    /barcode [ barcode {} forall ] def
+    /barlen barcode length def
+
+    ccb {/encoding (ccb) def} if
+
+    /encb {
+        /in exch def
+        /inlen in length def
+        /out inlen 6 idiv 5 mul inlen 6 mod add array def
+        0 1 inlen 6 idiv 1 sub {
+            /k exch def
+            /msbs [ in k 6 mul 3 getinterval aload pop ] def
             /mscs [
-                msbs aload pop exch 256 mul add exch 65536 mul add 
-                3 {dup 900 mod exch 900 idiv} repeat 
+                msbs aload pop exch 256 mul add exch 65536 mul add
+                3 {dup 900 mod exch 900 idiv} repeat
             ] def
-            /lsbs [barcode i 6 mul 3 add 3 getinterval {} forall] def
+            /lsbs [ in k 6 mul 3 add 3 getinterval aload pop ] def
             /lscs [
                 lsbs aload pop exch 256 mul add exch 65536 mul add
                 3 {dup 900 mod exch 900 idiv} repeat
             ] def
-            /cws 5 array def
             lscs 0 get mscs 0 get 316 mul add
-            cws 4 2 index 900 mod put
+            out k 5 mul 4 add 2 index 900 mod put
             900 idiv lscs 1 get add mscs 0 get 641 mul add mscs 1 get 316 mul add
-            cws 3 2 index 900 mod put 
-            900 idiv lscs 2 get add mscs 0 get 20 mul add mscs 1 get 641 mul add mscs 2 get 316 mul add 
-            cws 2 2 index 900 mod put
+            out k 5 mul 3 add 2 index 900 mod put
+            900 idiv lscs 2 get add mscs 0 get 20 mul add mscs 1 get 641 mul add mscs 2 get 316 mul add
+            out k 5 mul 2 add 2 index 900 mod put
             900 idiv lscs 3 get add mscs 1 get 20 mul add mscs 2 get 641 mul add
-            cws 1 2 index 900 mod put
+            out k 5 mul 1 add 2 index 900 mod put
             900 idiv mscs 2 get 20 mul add
-            cws 0 3 -1 roll 900 mod put
-            datcws i 5 mul 1 add cws putinterval 
+            out k 5 mul 3 -1 roll 900 mod put
         } for
-
-        % Add the remaining bytes to the end of the codewords
-        /rem barlen 6 mod def
+        /rem inlen 6 mod def
         rem 0 ne {
-            datcws datcws length rem sub 
-            [ barcode barlen rem sub rem getinterval {} forall ] 
+            out out length rem sub
+            [ in inlen rem sub rem getinterval aload pop ]
             putinterval
         } if
-
-        ccb {/datcws [920 datcws aload pop] def} if
-
-    } ifelse
+        out
+    } bind def
+
+    encoding (byte) eq encoding (ccb) eq or {
+        /datcws barlen 6 idiv 5 mul barlen 6 mod add 1 add array def
+        datcws 0 barlen 6 mod 0 eq {924} {901} ifelse put
+        datcws 1 barcode encb putinterval
+        encoding (ccb) eq {/datcws [920 datcws aload pop] def} if
+    } if
+
+    encoding (auto) eq {
+
+        % Modes and text submodes
+        /T 0 def  /N 1 def  /B 2 def
+        /A 0 def  /L 1 def  /M 2 def  /P 3 def
+        
+        % Special function characters for mode switching
+        /tl -1 def  /nl -2 def  /bl -3 def  /bl6 -4 def  /bs -5 def
+        
+        % Special function characters for text mode
+        /al -6 def  /ll -7 def  /ml -8 def  /pl -9 def  /as -10 def  /ps -11 def
+        
+        % Character maps for each state
+        /charmaps [
+          %  A    L    M    P
+          [ (A)  (a)  (0)  (;) ]  % 0
+          [ (B)  (b)  (1)  (<) ]  % 1
+          [ (C)  (c)  (2)  (>) ]  % 2
+          [ (D)  (d)  (3)  (@) ]  % 3
+          [ (E)  (e)  (4)  ([) ]  % 4
+          [ (F)  (f)  (5)   92 ]  % 5
+          [ (G)  (g)  (6)  (]) ]  % 6
+          [ (H)  (h)  (7)  (_) ]  % 7
+          [ (I)  (i)  (8)  (`) ]  % 8
+          [ (J)  (j)  (9)  (~) ]  % 9
+          [ (K)  (k)  (&)  (!) ]  % 10
+          [ (L)  (l)   13   13 ]  % 11
+          [ (M)  (m)    9    9 ]  % 12
+          [ (N)  (n)  (,)  (,) ]  % 13
+          [ (O)  (o)  (:)  (:) ]  % 14
+          [ (P)  (p)  (#)   10 ]  % 15
+          [ (Q)  (q)  (-)  (-) ]  % 16
+          [ (R)  (r)  (.)  (.) ]  % 17
+          [ (S)  (s)  ($)  ($) ]  % 18
+          [ (T)  (t)  (/)  (/) ]  % 19
+          [ (U)  (u)  (+)  (") ]  % 20
+          [ (V)  (v)  (%)  (|) ]  % 21
+          [ (W)  (w)  (*)  (*) ]  % 22
+          [ (X)  (x)  (=)   40 ]  % 23
+          [ (Y)  (y)  (^)   41 ]  % 24
+          [ (Z)  (z)   pl  (?) ]  % 25
+          [ ( )  ( )  ( )  ({) ]  % 26
+          [  ll   as   ll  (}) ]  % 27
+          [  ml   ml   al  (') ]  % 28
+          [  ps   ps   ps   al ]  % 29
+        ] def
+        
+        % Invert charmaps to give character to value maps for each state
+        /charvals [ 30 dict 30 dict 30 dict 30 dict ] def
+        /alltext 104 dict def
+        0 1 charmaps length 1 sub {
+          /i exch def
+          /encs charmaps i get def
+          0 1 3 {
+            /j exch def
+            encs j get dup type /stringtype eq {0 get} if  % convert string to ASCII if required
+            dup charvals j get exch i put
+            alltext exch -1 put
+          } for
+        } for
+        
+        /e 10000 def  % "Empty"
+        
+        /latlen [  % Bit length of latch between submodes
+        % To:  A  L  M  P      From
+            [  0  1  1  2 ]  % A
+            [  2  0  1  2 ]  % L
+            [  1  1  0  1 ]  % M
+            [  1  2  2  0 ]  % P
+        ] def
+        
+        /latseq [  % Latch sequences between submodes
+        % To: A       L       M       P               From
+            [ []      [ll]    [ml]    [ml pl]    ]  % A
+            [ [ml al] []      [ml]    [ml pl]    ]  % L
+            [ [al]    [ll]    []      [pl]       ]  % M
+            [ [al]    [al ll] [al ml] []         ]  % P
+        ] def
+        
+        /shftlen [  % Bit length of shift to submode
+        % To:  A  L  M  P      From
+            [  e  e  e  1 ]  % A
+            [  1  e  e  1 ]  % L
+            [  e  e  e  1 ]  % M
+            [  e  e  e  e ]  % P
+        ] def
+        
+        % Determine runlengths of digits
+        /numdigits [ barlen {0} repeat 0 ] def
+        /numtext   [ barlen {0} repeat 0 ] def
+        /numbytes  [ barlen {0} repeat 0 ] def
+        barlen 1 sub -1 0 {
+            /i exch def
+            barcode i get dup 48 ge exch 57 le and {
+                numdigits i numdigits i 1 add get 1 add put
+            } if
+            alltext barcode i get known numdigits i get 13 lt and {
+                numtext i numtext i 1 add get 1 add put
+            } if
+            numtext i get 5 lt numdigits i get 13 lt and {
+                numbytes i numbytes i 1 add get 1 add put
+            } if
+        } for
+        /numdigits numdigits 0 barlen getinterval def
+        /numtext   numtext   0 barlen getinterval def
+        /numbytes  numbytes  0 barlen getinterval def
+        
+        /seq [] def /seqlen 0 def /state B def /p 0 def {  % loop
+            p barlen eq {exit} if
+            /n numdigits p get def
+            n 13 ge {
+                /seq [
+                    seq aload pop
+                    nl
+                    [ barcode p n getinterval aload pop ]
+                ] def
+                /state N def
+                /p p n add def
+                /seqlen seqlen 1 add n add def
+            } {  % next
+            /t numtext p get def
+            t 5 ge {
+                /seq [
+                    seq aload pop
+                    state T ne {tl} if
+                    [ barcode p t getinterval aload pop ]
+                ] def
+                /state T def
+                /p p t add def
+                /seqlen seqlen 1 add t add def  % ish
+            } {  % next
+            /b numbytes p get def
+            b 1 eq state T eq and {
+                /seq [
+                    seq aload pop
+                    bs
+                    [ barcode p get ]
+                ] def
+                /p p b add def
+                /seqlen seqlen 2 add def
+            } {  % next
+                /seq [
+                    seq aload pop
+                    b 6 mod 0 ne {bl} {bl6} ifelse
+                    [ barcode p b getinterval aload pop ]
+                ] def
+                /state B def
+                /p p b add def
+                /seqlen seqlen 1 add b add def
+            } ifelse } ifelse } ifelse
+        } loop
+        
+        /latchcws <<
+            tl 900  bl 901  bl6 924  nl 902  bs 913
+        >> def
+        
+        % Submode encoding functions
+        /enca {charvals A get exch get} bind def
+        /encl {charvals L get exch get} bind def
+        /encm {charvals M get exch get} bind def
+        /encp {charvals P get exch get} bind def
+        /textencfuncs [ /enca /encl /encm /encp ] def
+        
+        /addtotext {
+            text exch l exch put
+            /l l 1 add def
+        } bind def
+        
+        /enct {
+        
+            /in exch def
+        
+            /curlen [  e  e  e  e ] def
+            curlen submode 0 put
+            /curseq [ [] [] [] [] ] def
+        
+            % Derive the optimal sequences ending in each submode
+            in {
+        
+                /char exch def
+        
+                % Check for optimisations in the current sequences by latching from x to y
+                {  % loop
+                    /imp false def
+                    [ A L M P ] {
+                        /x exch def
+                        [ A L M P ] {
+                            /y exch def
+                            /cost curlen x get latlen x get y get add def
+                            cost curlen y get lt {
+                                curlen y cost put
+                                curseq y [
+                                    curseq x get aload pop
+                                    latseq x get y get aload pop
+                                ] put
+                                /imp true def
+                            } if
+                        } forall
+                    } forall
+                    imp not {exit} if  % Repeat unless no improvement
+                } loop
+        
+                % Determine optimal next sequences for each valid encoding
+                /nxtlen [ e e e e ] def
+                /nxtseq 4 array def
+        
+                [ A L M P ] {
+                    /x exch def
+        
+                    { % loop for common exit
+        
+                        charvals x get char known not {exit} if
+        
+                        % Extend directly
+                        /cost curlen x get 1 add def
+                        cost nxtlen x get lt {
+                            nxtlen x cost put
+                            nxtseq x [ curseq x get aload pop char ] put
+                        } if
+        
+                        % Optimise for direct shifts from y to x
+                        [ A L M P ] {
+                            /y exch def
+                            x y ne {
+                                /cost curlen y get shftlen y get x get add 1 add def
+                                cost nxtlen y get lt {
+                                    nxtlen y cost put
+                                    nxtseq y [
+                                        curseq y get aload pop
+                                        x A eq {as} {ps} ifelse
+                                        char
+                                    ] put
+                                } if
+                            } if
+                        } forall
+        
+                        exit
+                    } loop
+        
+                } forall
+        
+                /curlen nxtlen def
+                /curseq nxtseq def
+        
+            } forall
+        
+            % Select the optimal sequence
+            /minseq e def
+            [ A L M P ] {
+                /k exch def
+                curlen k get minseq lt {
+                    /minseq curlen k get def
+                    /txtseq curseq k get def
+                } if
+            } forall
+        
+            % Encode the sequence
+            /text minseq array def
+            /k 0 def /l 0 def {
+                k txtseq length ge {exit} if
+        
+                /char txtseq k get def
+        
+                % Encode character
+                char textencfuncs submode get load exec addtotext
+                /k k 1 add def
+        
+                % Encode shifted next character
+                char as eq char ps eq or {
+                    txtseq k get char as eq {enca} {encp} ifelse addtotext
+                    /k k 1 add def
+                } if
+        
+                % Latches to new submode
+                char al eq {/submode A def} if
+                char ll eq {/submode L def} if
+                char ml eq {/submode M def} if
+                char pl eq {/submode P def} if
+            } loop
+        
+            text length 2 mod 1 eq {
+                submode P eq {
+                    /pad al encp def
+                    /submode A def
+                } {
+                    /pad ps textencfuncs submode get load exec def
+                } ifelse
+                /text [ text aload pop pad ] def
+            } if
+        
+            /out text length 2 idiv array def
+            0 1 out length 1 sub {
+                /k exch def
+                out k text k 2 mul get 30 mul text k 2 mul 1 add get add put
+            } for
+        
+            out
+        
+        } bind def
+        
+        /encn {
+            /in exch def
+            /out [] def
+            0 44 in length 1 sub {
+                /k exch def
+                /gmod [
+                    1 in k in length k sub dup 44 gt {pop 44} if getinterval
+                    {48 sub} forall
+                ] def
+                /cwn [] def {
+                    /dv 900 def
+                    /gmul [] def /val 0 def {
+                        gmod length 0 eq {exit} if
+                        /val val 10 mul gmod 0 get add def
+                        /gmod gmod 1 gmod length 1 sub getinterval def
+                        val dv lt {
+                            gmul length 0 ne {
+                                /gmul [ gmul aload pop 0 ] def
+                            } if
+                        } {
+                            /gmul [ gmul aload pop val dv idiv ] def
+                        } ifelse
+                        /val val dv mod def
+                    } loop
+                    /dv val def
+                    /cwn [ dv cwn aload pop ] def
+                    /gmod gmul def
+                    gmul length 0 eq {exit} if
+                } loop
+                /out [ out aload pop cwn aload pop ] def
+            } for
+            out
+        } bind def
+       
+        /encfuncs [ /enct /encn /encb ] def
+        
+        /addtocws {
+            dup datcws j 3 -1 roll putinterval
+            length j add /j exch def
+        } bind def
+        
+        % Encode the sequence
+        /state T def /submode A def
+        /datcws seqlen array def
+        /i 0 def /j 0 def {
+            i seq length ge {exit} if
+            /chars seq i get def
+            chars type /arraytype eq {  % Encode data according to mode
+                chars encfuncs state get load exec addtocws
+            } {  % Encode the latch to new state or byte shift
+                [ latchcws chars get ] addtocws
+                chars tl eq {/state T def /submode A def} if
+                chars nl eq {/state N def} if
+                chars bl eq chars bl6 eq or {/state B def} if
+                chars bs eq {
+                    /i i 1 add def
+                    seq i get encb addtocws
+                } if
+            } ifelse
+            /i i 1 add def
+        } loop
+        /datcws datcws 0 j getinterval def
+    } if
 
     % Basic metrics for the each symbol
     %     c  r ecw  rl rc rr
@@ -12226,15 +14189,21 @@
 /micropdf417 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER micropdf417--
 
 % --BEGIN ENCODER datamatrix--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Data Matrix
 % --EXAM: This is Data Matrix!
-% --EXOP: rows=32 columns=32
+% --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp datamatrix 0.0 2014121100 198474 217339
+%%BeginData:        844 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /datamatrix {
@@ -12247,8 +14216,6 @@
     /dontdraw false def
     /columns 0 def
     /rows 0 def
-    /encoding (ascii) def
-    /raw false def
     /parse false def
     /parsefnc false def
 
@@ -12289,79 +14256,32 @@
 
     /barlen barcode length def
 
-    raw {/encoding (raw) def} if
-
-    encoding (raw) eq {
-        /cws barlen array def
-        /i 0 def /j 0 def
-        { % loop
-            i barlen eq {exit} if
-            /cw barcode i 1 add 3 getinterval cvi def
-            cws j cw put
-            /i i 4 add def
-            /j j 1 add def
-        } loop
-        /cws cws 0 j getinterval def
-    } if
-
-    % Special function characters
-    /fn1 -1 def
-
-    encoding (ascii) eq {
-        /fncvals <<
-            (FNC1) fn1
-        >> def
-        /msg barlen array def
-        /i 0 def /j 0 def {
-            i barlen eq {exit} if
-            /char barcode i get def
-            parsefnc char 94 eq and i barlen 4 sub lt and {
-                barcode i 1 add get 94 ne {
-                    /char fncvals barcode i 1 add 4 getinterval get def
-                    /i i 4 add def
-                } {
-                    /i i 1 add def
-                } ifelse
-            } if
-            msg j char put
-            /i i 1 add def
-            /j j 1 add def
-        } loop
-        /msg msg 0 j getinterval def
-        /msglen msg length def
-
-        /cws msglen 2 mul array def
-        /i 0 def /j 0 def
-        { % loop
-            i msglen eq {exit} if
-            /char msg i get def
-            char fn1 eq {  % FNC1
-                cws j 232 put
+    % Convert input into bytes accounting for FNC characters
+    /fnc1 -1 def  /prog -2 def  /m05 -3 def  /m06 -4 def
+    /fncvals <<
+        (FNC1) fnc1
+        (PROG) prog
+        (MAC5) m05
+        (MAC6) m06
+    >> def
+    /msg barlen array def
+    /i 0 def /j 0 def {
+        i barlen eq {exit} if
+        /char barcode i get def
+        parsefnc char 94 eq and i barlen 4 sub lt and {
+            barcode i 1 add get 94 ne {
+                /char fncvals barcode i 1 add 4 getinterval get def
+                /i i 4 add def
+            } {
                 /i i 1 add def
-                /j j 1 add def
-            } { char 48 ge char 57 le and i msglen 1 sub lt and {
-                msg i 1 add get dup 48 ge exch 57 le and {  % Digit pair
-                    cws j msg i get 48 sub 10 mul msg i 1 add get 48 sub add 130 add put
-                    /i i 2 add def
-                    /j j 1 add def
-                } {  % Singular digit
-                    cws j char 1 add put
-                    /i i 1 add def
-                    /j j 1 add def
-                } ifelse
-            } { char 127 le {  % ASCII
-                cws j char 1 add put
-                /i i 1 add def
-                /j j 1 add def
-            } {  % Extended ASCII
-                cws j 235 put
-                cws j 1 add char 127 sub put
-                /i i 1 add def
-                /j j 2 add def
-            } ifelse } ifelse } ifelse
-        } loop
-        /cws cws 0 j getinterval def
-    } if
+            } ifelse
+        } if
+        msg j char put
+        /i i 1 add def
+        /j j 1 add def
+    } loop
+    /msg msg 0 j getinterval def
+    /msglen msg length def
 
     % Basic metrics for the each symbol
     %    rows  cols  regh  regv  rscw  rsbl
@@ -12400,11 +14320,489 @@
         [  16    48     1     2    28     1 ]
     ] def
 
-    % Select metrics of an appropriate symbol
+    % Create array of codewords remaining to make a full symbol
     /urows rows def
     /ucols columns def
-    /i 0 def
-    { % loop
+    /fullcws [] def
+    metrics {
+        /m exch def
+        /rows m 0 get def                          % Rows in symbol
+        /cols m 1 get def                          % Columns in symbol
+        /regh m 2 get def                          % Horizontal regions
+        /regv m 3 get def                          % Vertical regions
+        /rscw m 4 get def                          % Error correction codewords
+        /rsbl m 5 get def                          % Error correction blocks
+        /mrows rows 2 regh mul sub def             % Rows in the mapping matrix
+        /mcols cols 2 regv mul sub def             % Columns in the mapping matrix
+        /ncws mrows mcols mul 8 idiv rscw sub def  % Data codewords
+        /okay true def
+        urows 0 ne urows rows ne and {/okay false def} if
+        ucols 0 ne ucols cols ne and {/okay false def} if
+        urows 0 eq ucols 0 eq or rows cols ne and {/okay false def} if
+        okay {/fullcws [ fullcws aload pop ncws ] def} if
+    } forall
+    /numremcws [ 1558 {10000} repeat ] def
+    fullcws {numremcws exch 1 sub 1 put} forall
+    1556 -1 0 {
+        /i exch def
+        numremcws i get 1 ne {
+            numremcws i numremcws i 1 add get 1 add put
+        } if
+    } for
+
+    % Special characters
+    /lC    -5 def  /lB    -6 def  /lX    -7 def  /lT    -8 def  /lE    -9 def  /unl -10 def
+    /sapp -11 def  /usft -12 def  /sft1 -13 def  /sft2 -14 def  /sft3 -15 def  /eci -16 def  /pad -17 def
+    /unlcw 254 def
+  
+    /Avals <<
+        0 1 128 {dup 1 add} for
+        pad 129
+        0 1 99 {  % Double digits
+            dup 10 2 string cvrs (00) 2 string copy dup 2 3 index length sub 4 -1 roll putinterval
+            exch 130 add
+        } for
+        229 [ lC lB fnc1 sapp prog usft m05 m06 lX lT lE eci ] {exch 1 add dup} forall pop
+    >> def
+    /Avals <<
+        Avals {[exch]} forall
+    >> def
+    
+    /CNvals <<
+        sft1 0
+        sft2 1
+        sft3 2
+        32   3
+        48 1 57 {dup 44 sub} for  % 0-9
+        65 1 90 {dup 51 sub} for  % A-Z
+    >> def
+    /C1vals << 0 1 31 {dup} for >> def
+    /C2vals <<
+        33 1 47 {dup 33 sub} for
+        58 1 64 {dup 43 sub} for
+        91 1 95 {dup 69 sub} for
+        fnc1 27
+        usft 30
+    >> def
+    /C3vals << 96 1 127 {dup 96 sub} for >> def
+    /Cvals <<
+        CNvals {[exch]} forall
+        C1vals {[exch CNvals sft1 get exch]} forall
+        C2vals {[exch CNvals sft2 get exch]} forall
+        C3vals {[exch CNvals sft3 get exch]} forall
+    >> def
+    
+    /TNvals <<
+        sft1 0
+        sft2 1
+        sft3 2
+        32   3
+        48 1  57 {dup 44 sub} for  % 0-9
+        97 1 122 {dup 83 sub} for  % a-z
+    >> def
+    /T1vals << 0 1 31 {dup} for >> def
+    /T2vals <<
+        33 1 47 {dup 33 sub} for
+        58 1 64 {dup 43 sub} for
+        91 1 95 {dup 69 sub} for
+        fnc1 27
+        usft 30
+    >> def
+    /T3vals <<
+         96 0
+         65 1  90 {dup 64 sub} for
+        123 1 127 {dup 96 sub} for
+    >> def
+    /Tvals <<
+        TNvals {[exch]} forall
+        T1vals {[exch TNvals sft1 get exch]} forall
+        T2vals {[exch TNvals sft2 get exch]} forall
+        T3vals {[exch TNvals sft3 get exch]} forall
+    >> def
+    
+    % Extended ASCII mappings
+    128 1 255 {
+        /i exch def
+        Avals i [ Avals usft get aload pop Avals i 128 sub get aload pop ] put
+        Cvals i [ Cvals usft get aload pop Cvals i 128 sub get aload pop ] put
+        Tvals i [ Tvals usft get aload pop Tvals i 128 sub get aload pop ] put
+    } for
+    
+    /Xvals <<
+        13 0
+        42 1
+        62 2
+        32 3
+        48 1 57 {dup 44 sub} for
+        65 1 90 {dup 51 sub} for
+    >> def
+    /Xvals <<
+        Xvals {[exch]} forall
+    >> def
+    
+    /Evals <<
+        64 1 94 {dup 64 sub} for
+        unl 31
+        32 1 63 {dup} for
+    >> def
+    /Evals <<
+        Evals {[exch]} forall
+    >> def
+    
+    /Bvals <<
+        0 1 255 {dup} for
+    >> def
+    /Bvals <<
+        Bvals {[exch]} forall
+    >> def
+    
+    /encvals [ Avals Cvals Tvals Xvals Evals Bvals ] def
+    
+    /numD [ msglen {0} repeat 0 ] def
+    /nextXterm [ msglen {0} repeat 9999 ] def
+    /nextNonX  [ msglen {0} repeat 9999 ] def
+    msglen 1 sub -1 0 {
+        /i exch def
+        /barchar msg i get def
+        barchar 48 ge barchar 57 le and {
+            numD i numD i 1 add get 1 add put
+        } if
+        barchar 13 eq barchar 42 eq or barchar 62 eq or {
+            nextXterm i 0 put
+        } {
+            nextXterm i nextXterm i 1 add get 1 add put
+        } ifelse
+        Xvals barchar known not {
+            nextNonX i 0 put
+        } {
+            nextNonX i nextNonX i 1 add get 1 add put
+        } ifelse
+    } for
+    /nextXterm [nextXterm {dup 10000 gt {pop 10000} if} forall] def
+    /nextNonX  [nextNonX  {dup 10000 gt {pop 10000} if} forall] def
+    
+    /isD  {char 48 ge char 57 le and} bind def
+    /isC  {CNvals char known} bind def
+    /isT  {TNvals char known} bind def
+    /isX  {Xvals char known} bind def
+    /isE  {Evals char known} bind def
+    /isEA {char 127 gt} bind def
+    /isFN {char 0 lt} bind def
+    /XtermFirst {dup nextXterm exch get exch nextNonX exch get lt} bind def
+    
+    /A 0 def  /C 1 def  /T 2 def  /X 3 def  /E 4 def  /B 5 def
+
+    /lookup {
+        /ac 1 def /cc 2 def /tc 2 def /xc 2 def /ec 2 def /bc 2.25 def
+        mode A eq {/ac 0 def /cc 1 def /tc 1 def /xc 1 def /ec 1 def /bc 1.25 def} if
+        mode C eq {/cc 0 def} if
+        mode T eq {/tc 0 def} if
+        mode X eq {/xc 0 def} if
+        mode E eq {/ec 0 def} if
+        mode B eq {/bc 0 def} if
+        1 {  % common exit
+            /k 0 def {  % loop
+                i k add msglen eq {
+                    [/ac /cc /tc /xc /ec /bc] {dup load ceiling def} forall
+                    true [   cc tc xc ec bc] {ac exch le and} forall {A exit} if
+                    true [ac cc tc xc ec   ] {bc exch lt and} forall {B exit} if
+                    true [ac cc tc xc    bc] {ec exch lt and} forall {E exit} if
+                    true [ac cc    xc ec bc] {tc exch lt and} forall {T exit} if
+                    true [ac cc tc    ec bc] {xc exch lt and} forall {X exit} if
+                    C exit
+                } if
+                /char msg i k add get def
+                /ac ac isD {1 2 div add} {isEA {ceiling 2 add} {1 add       } ifelse} ifelse def
+                /cc cc isC {2 3 div add} {isEA { 8 3 div add } { 4 3 div add} ifelse} ifelse def
+                /tc tc isT {2 3 div add} {isEA { 8 3 div add } { 4 3 div add} ifelse} ifelse def
+                /xc xc isX {2 3 div add} {isEA {13 3 div add } {10 3 div add} ifelse} ifelse def
+                /ec ec isE {3 4 div add} {isEA {17 4 div add } {13 4 div add} ifelse} ifelse def
+                /bc bc isFN {4 add} {1 add} ifelse def
+                k 4 ge {
+                    true [   cc tc xc ec bc] {ac 1 add exch le and} forall {A exit} if
+                    bc 1 add ac le {B exit} if
+                    true [   cc tc xc ec   ] {bc 1 add exch lt and} forall {B exit} if
+                    true [ac cc tc xc    bc] {ec 1 add exch lt and} forall {E exit} if
+                    true [ac cc    xc ec bc] {tc 1 add exch lt and} forall {T exit} if
+                    true [ac cc tc    ec bc] {xc 1 add exch lt and} forall {X exit} if
+                    true [ac    tc    ec bc] {cc 1 add exch lt and} forall {
+                        cc xc lt {C exit} if
+                        cc xc eq {i k add 1 add XtermFirst {X exit} {C exit} ifelse} if
+                    } if
+                } if
+                /k k 1 add def
+            } loop
+        } repeat
+    } bind def
+    
+    /addtocws {
+        dup cws exch j exch putinterval
+        /j exch length j add def
+    } bind def
+    
+    /encA {
+        1 {  % Common exit
+            numD i get 2 ge {
+                2 string dup 0 msg i get put dup 1 msg i 1 add get put Avals exch get addtocws
+                /i i 2 add def
+                exit
+            } if
+            /newmode lookup def
+            newmode mode ne {
+                Avals [-1 lC lT lX lE lB] newmode get get addtocws
+                /mode newmode def
+                exit
+            } if
+            Avals msg i get get addtocws
+            /i i 1 add def
+            exit
+        } repeat
+    } bind def
+    
+    /CTXvalstocws {
+        /in exch def
+        mark
+        0 3 in length 1 sub {
+            in exch 3 getinterval 0 exch {add 40 mul} forall 40 idiv 1 add
+            dup 256 idiv exch 256 mod
+        } for
+        counttomark array astore exch pop
+    } bind def
+    
+    /encCTX {
+        /p 0 def
+        /ctxvals 2500 array def
+    
+        % Lookup the values for each character
+        {
+            i msglen eq {exit} if
+            encvals mode get msg i get known not {exit} if
+            p 3 mod 0 eq {
+                lookup mode ne {
+                    ctxvals 0 p getinterval CTXvalstocws addtocws
+                    [unlcw] addtocws
+                    /mode A def
+                    exit
+                } if
+                msglen i sub 3 le {  % Check end of data conditions
+                    /remcws numremcws j p 3 idiv 2 mul add get def
+                    /remvals [
+                        msg i msglen i sub getinterval {
+                            dup encvals mode get exch known {
+                                encvals mode get exch get aload pop
+                            } {  % Unencodable X12 characters
+                                pop -1 -1 -1 -1
+                            } ifelse
+                        } forall
+                    ] def
+                    remcws 2 eq remvals length 3 eq and {
+                        % Encode and omit unlatch
+                        [
+                            ctxvals 0 p getinterval aload pop
+                            remvals aload pop
+                        ] CTXvalstocws addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                    remcws 2 eq remvals length 2 eq and mode X ne and {
+                        % Encode with sft1 as third value, omit unlatch
+                        [
+                            ctxvals 0 p getinterval aload pop
+                            remvals aload pop
+                            encvals mode get sft1 get aload pop
+                        ] CTXvalstocws addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                    remcws 2 eq remvals length 1 eq and {
+                        % Unlatch to ASCII
+                        ctxvals 0 p getinterval CTXvalstocws addtocws
+                        [unlcw] addtocws
+                        Avals msg i get get addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                    remcws 1 eq remvals length 1 eq and {
+                        % Implied unlatch to ASCII
+                        ctxvals 0 p getinterval CTXvalstocws addtocws
+                        Avals msg i get get addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                } if
+            } if
+            encvals mode get msg i get get
+            dup ctxvals exch p exch putinterval
+            /p exch length p add def
+            /i i 1 add def
+        } loop
+
+        % Backtrack to a boundary and return to ASCII
+        mode A ne {
+            {
+                p 3 mod 0 eq {exit} if
+                /i i 1 sub def
+                /p p encvals mode get msg i get get length sub def
+            } loop
+            [
+                ctxvals 0 p getinterval aload pop
+            ] CTXvalstocws addtocws
+            [unlcw] addtocws
+            /mode A def
+            % Encode something to avoid latching immediately back
+            i msglen ne {
+                numD i get 2 ge {
+                    2 string dup 0 msg i get put dup 1 msg i 1 add get put Avals exch get addtocws
+                    /i i 2 add def
+                } {
+                    Avals msg i get get addtocws
+                    /i i 1 add def
+                } ifelse
+            } if
+        } if
+    
+    } bind def
+    
+    /Evalstocws {
+        /in exch def
+        /inlen in length def
+        /outlen in length 4 div 3 mul ceiling cvi def
+        /in [ in aload pop 0 0 0 ] def
+        mark
+        0 4 inlen 1 sub {
+            in exch 4 getinterval 0 exch {or 6 bitshift} forall -6 bitshift
+            dup -16 bitshift 255 and exch
+            dup -8 bitshift 255 and exch
+            255 and
+        } for
+        counttomark array astore exch pop
+        0 outlen getinterval
+    } bind def
+    
+    /encE {
+        /p 0 def
+        /edifactvals 2100 array def
+    
+        % Lookup the values for each character
+        {
+            i msglen eq {exit} if
+            Evals msg i get known not {exit} if
+            p 4 mod 0 eq {
+                lookup mode ne {exit} if
+                msglen i sub 2 le {  % Check end of data conditions
+                    /remcws numremcws j p 4 idiv 3 mul add get def
+                    /remvals [
+                        msg i msglen i sub getinterval {
+                            dup Evals exch known {
+                                Evals exch get aload pop
+                            } {  % Unencodable EDIFACT characters
+                                pop -1 -1 -1 -1 -1
+                            } ifelse
+                        } forall
+                    ] def
+                    remcws 2 eq remvals length 2 eq and {
+                        % Implied unlatch to ASCII
+                        edifactvals 0 p getinterval Evalstocws addtocws
+                        Avals msg i get get addtocws
+                        Avals msg i 1 add get get addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                    remcws 2 eq remcws 1 eq or remvals length 1 eq and {
+                        % Implied unlatch to ASCII
+                        edifactvals 0 p getinterval Evalstocws addtocws
+                        Avals msg i get get addtocws
+                        /mode A def
+                        /i msglen def
+                        exit
+                    } if
+                } if
+            } if
+            Evals msg i get get
+            dup edifactvals exch p exch putinterval
+            /p exch length p add def
+            /i i 1 add def
+        } loop
+    
+        % Unlatch and pad with zeros until boundary
+        mode A ne {
+            /remcws numremcws j p 4 idiv 3 mul add 1 sub get 1 sub def
+            remcws 0 ne {  % Unlatch if we haven't filled symbol
+                Evals unl get
+                dup edifactvals exch p exch putinterval
+                /p exch length p add def
+            } if
+            edifactvals 0 p getinterval Evalstocws addtocws
+            /mode A def
+            % Encode something to avoid latching immediately back
+            i msglen ne {
+                numD i get 2 ge {
+                    2 string dup 0 msg i get put dup 1 msg i 1 add get put Avals exch get addtocws
+                    /i i 2 add def
+                } {
+                    Avals msg i get get addtocws
+                    /i i 1 add def
+                } ifelse
+            } if
+        } if
+
+    } bind def
+    
+    /encB {
+        /p 0 def /bvals 1558 array def {
+            i msglen eq {exit} if
+            lookup mode ne {exit} if
+            bvals p msg i get put
+            /p p 1 add def
+            /i i 1 add def
+        } loop
+        /remcws numremcws j p add get 1 sub def
+        /bvals [
+            remcws 0 eq i msglen eq and {  % Terminates symbol
+                0
+            } {
+                p 250 lt {p} {p 250 idiv 249 add p 250 mod} ifelse
+            } ifelse
+            bvals 0 p getinterval aload pop
+        ] def
+        0 1 bvals length 1 sub {  % Pseudo-randomise based on codeword position
+            /p exch def
+            j p add 1 add 149 mul 255 mod 1 add bvals p get add
+            dup 256 ge {256 sub} if
+            bvals exch p exch put
+        } for
+        bvals addtocws
+        /mode A def
+    } bind def
+    
+    % Derive the codewords
+    /cws 1558 array def
+    /mode A def /i 0 def /j 0 def {
+        i msglen ge {exit} if
+        [ /encA /encCTX /encCTX /encCTX /encE /encB ] mode get load exec
+    } loop
+    /cws cws 0 j getinterval def
+
+    % Extend codewords to fill symbol with pseudo-randomised pad characters
+    /datlen cws length def
+    /remcws numremcws j 1 sub get 1 sub def
+    remcws 0 gt {
+        /cws [ cws aload pop remcws {129} repeat ] def
+        datlen 1 add 1 datlen remcws add 1 sub {
+            /i exch def
+            i 1 add 149 mul 253 mod 1 add 129 add
+            dup 254 gt {254 sub} if
+            cws exch i exch put
+        } for
+    } if
+
+    % Lookup symbol metrics based on number of codewords and user specification
+    /i 0 def { % loop
         /m metrics i get def
         /rows m 0 get def                          % Rows in symbol
         /cols m 1 get def                          % Columns in symbol
@@ -12418,24 +14816,12 @@
         /rcols mcols regv idiv def                 % Columns per region
         /ncws mrows mcols mul 8 idiv rscw sub def  % Data codewords
         /okay true def
-        cws length ncws gt           {/okay false def} if
+        cws length ncws ne           {/okay false def} if
         urows 0 ne urows rows ne and {/okay false def} if
         ucols 0 ne ucols cols ne and {/okay false def} if
         okay {exit} if
         /i i 1 add def
     } loop
-
-    % Extend cws to ncws codewords by addition of pseudo-randomised pad characters
-    cws length ncws lt {
-        /datlen cws length def
-        /cws [ cws {} forall ncws datlen sub {129} repeat ] def
-        datlen 1 add 1 ncws 1 sub {
-            /i exch def
-            i 1 add 149 mul 253 mod 1 add 129 add
-            dup 254 gt {254 sub} if
-            cws exch i exch put
-        } for
-    } if
 
     % De-interleave the codewords into blocks
     /cwbs rsbl array def  % Array of data codeword blocks
@@ -12659,15 +15045,21 @@
 /datamatrix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER datamatrix--
 
 % --BEGIN ENCODER qrcode--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: QR Code
-% --EXAM: http://www.terryburton.co.uk/barcodewriter/
+% --EXAM: http://goo.gl/0bis
 % --EXOP: eclevel=M
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp qrcode 0.0 2014121100 261342 297027
+%%BeginData:       1004 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /qrcode {
@@ -12678,12 +15070,11 @@
     /barcode exch def
 
     /dontdraw false def
-    /format (full) def     % full or micro
-    /version (unset) def
+    /format (full) def     % full or micro or any
+    /version (unset) def   % 1-40 or M1-M4
     /eclevel (unset) def   % L, M, Q or H
-    /encoding (unset) def
-    /raw false def
     /parse false def
+    /parsefnc false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -12719,353 +15110,420 @@
 
     /barlen barcode length def
 
+    % Convert input into bytes accounting for FNC characters
+    /fn1 -1 def
+    /fncvals <<
+        (FNC1) fn1
+    >> def
+    /msg barlen array def
+    /i 0 def /j 0 def {
+        i barlen eq {exit} if
+        /char barcode i get def
+        parsefnc char 94 eq and i barlen 4 sub lt and {
+            barcode i 1 add get 94 ne {
+                /char fncvals barcode i 1 add 4 getinterval get def
+                /i i 4 add def
+            } {
+                /i i 1 add def
+            } ifelse
+        } if
+        msg j char put
+        /i i 1 add def
+        /j j 1 add def
+    } loop
+    /msg msg 0 j getinterval def
+    /msglen msg length def
+
+    % If FNC1 in first position then escape % as %%
+    /fnc1first false def
+    msglen 0 gt {
+        msg 0 get fn1 eq {
+            /fnc1first true def
+            /msg [ msg 1 msglen 1 sub getinterval { dup 37 eq {dup} if } forall ] def
+            /msglen msg length def
+        } if
+    } if
+
     % Default error correction level
     eclevel (unset) eq {/eclevel format (full) eq {(M)} {(L)} ifelse def} if
 
     % Convert from input into message bitstream
-    raw {/encoding (raw) def} if
-    encoding (raw) eq {
-        /msgbits barcode def 
-    } {
-
-        % Symbol capacities
-        /fullcaps <<
-            /numeric <<
-                /L [   41    77   127   187   255   322   370   461   552   652    %  1-L - 10-L
-                      772   883  1022  1101  1250  1408  1548  1725  1903  2061    % 11-L - 20-L
-                     2232  2409  2620  2812  3057  3283  3517  3669  3909  4158    % 21-L - 30-L
-                     4417  4686  4965  5253  5529  5836  6153  6479  6743  7089 ]  % 31-L - 40-L
-                /M [   34    63   101   149   202   255   293   365   432   513    %  1-M - 10-M
-                      604   691   796   871   991  1082  1212  1346  1500  1600    % 11-M - 20-M
-                     1708  1872  2059  2188  2395  2544  2701  2857  3035  3289    % 21-M - 30-M
-                     3486  3693  3909  4134  4343  4588  4775  5039  5313  5596 ]  % 31-M - 40-M
-                /Q [   27    48    77   111   144   178   207   259   312   364    %  1-Q - 10-Q
-                      427   489   580   621   703   775   876   948  1063  1159    % 11-Q - 20-Q
-                     1224  1358  1468  1588  1718  1804  1933  2085  2181  2358    % 21-Q - 30-Q
-                     2473  2670  2805  2949  3081  3244  3417  3599  3791  3993 ]  % 31-Q - 40-Q
-                /H [   17    34    58    82   106   139   154   202   235   288    %  1-H - 10-H
-                      331   374   427   468   530   602   674   746   813   919    % 11-H - 20-H
-                      969  1056  1108  1228  1286  1425  1501  1581  1677  1782    % 21-H - 30-H
-                     1897  2022  2157  2301  2361  2524  2625  2735  2927  3057 ]  % 31-H - 40-H
-            >>
-            /alphanumeric <<
-                /L [   25    47    77   114   154   195   224   279   335   395    %  1-L - 10-L
-                      468   535   619   667   758   854   938  1046  1153  1249    % 11-L - 20-L
-                     1352  1460  1588  1704  1853  1990  2132  2223  2369  2520    % 21-L - 30-L
-                     2677  2840  3009  3183  3351  3537  3729  3927  4087  4296 ]  % 31-L - 40-L
-                /M [   20    38    61    90   122   154   178   221   262   311    %  1-M - 10-M
-                      366   419   483   528   600   656   734   816   909   970    % 11-M - 20-M
-                     1035  1134  1248  1326  1451  1542  1637  1732  1839  1994    % 21-M - 30-M
-                     2113  2238  2369  2506  2632  2780  2894  3054  3220  3391 ]  % 31-M - 40-M
-                /Q [   16    29    47    67    87   108   125   157   189   221    %  1-Q - 10-Q
-                      259   296   352   376   426   470   531   574   644   702    % 11-Q - 20-Q
-                      742   823   890   963  1041  1094  1172  1263  1322  1429    % 21-Q - 30-Q
-                     1499  1618  1700  1787  1867  1966  2071  2181  2298  2420 ]  % 31-Q - 40-Q
-                /H [   10    20    35    50    64    84    93   122   143   174    %  1-H - 10-H
-                      200   227   259   283   321   365   408   452   493   557    % 11-H - 20-H
-                      587   640   672   744   779   864   910   958  1016  1080    % 21-H - 30-H
-                     1150  1226  1307  1394  1431  1530  1591  1658  1774  1852 ]  % 31-H - 40-H
-            >>
-            /byte <<
-                /L [   17    32    53    78   106   134   154   192   230   271    %  1-L - 10-L
-                      321   367   425   458   520   586   644   718   792   858    % 11-L - 20-L
-                      929  1003  1091  1171  1273  1367  1465  1528  1628  1732    % 21-L - 30-L
-                     1840  1952  2068  2188  2303  2431  2563  2699  2809  2953 ]  % 31-L - 40-L
-                /M [   14    26    42    62    84   106   122   152   180   213    %  1-M - 10-M
-                      251   287   331   362   412   450   504   560   624   666    % 11-M - 20-M
-                      711   779   857   911   997  1059  1125  1190  1264  1370    % 21-M - 30-M
-                     1452  1538  1628  1722  1809  1911  1989  2099  2213  2331 ]  % 31-M - 40-M
-                /Q [   11    20    32    46    60    74    86   108   130   151    %  1-Q - 10-Q
-                      177   203   241   258   292   322   364   394   442   482    % 11-Q - 20-Q
-                      509   565   611   661   715   751   805   868   908   982    % 21-Q - 30-Q
-                     1030  1112  1168  1228  1283  1351  1423  1499  1579  1663 ]  % 31-Q - 40-Q
-                /H [    7    14    24    34    44    58    64    84    98   119    %  1-H - 10-H
-                      137   155   177   194   220   250   280   310   338   382    % 11-H - 20-H
-                      403   439   461   511   535   593   625   658   698   742    % 21-H - 30-H
-                      790   842   898   958   983  1051  1093  1139  1219  1273 ]  % 31-H - 40-H
-            >>
-            /kanji <<
-                /L [   10    20    32    48    65    82    95   118   141   167    %  1-L - 10-L
-                      198   226   262   282   320   361   397   442   488   528    % 11-L - 20-L
-                      572   618   672   721   784   842   902   940  1002  1066    % 21-L - 30-L
-                     1132  1201  1273  1347  1417  1496  1577  1661  1729  1817 ]  % 31-L - 40-L
-                /M [    8    16    26    38    52    65    75    93   111   131    %  1-M - 10-M
-                      155   177   204   223   254   277   310   345   384   410    % 11-M - 20-M
-                      438   480   528   561   614   652   692   732   778   843    % 21-M - 30-M
-                      894   947  1002  1060  1113  1176  1224  1292  1362  1435 ]  % 31-M - 40-M
-                /Q [    7    12    20    28    37    45    53    66    80    93    %  1-Q - 10-Q
-                      109   125   149   159   180   198   224   243   272   297    % 11-Q - 20-Q
-                      314   348   376   407   440   462   496   534   559   604    % 21-Q - 30-Q
-                      634   684   719   756   790   832   876   923   972  1024 ]  % 31-Q - 40-Q
-                /H [    4     8    15    21    27    36    39    52    60    74    %  1-H - 10-H
-                       85    96   109   120   136   154   173   191   208   235    % 11-H - 20-H
-                      248   270   284   315   330   365   385   405   430   457    % 21-H - 30-H
-                      486   518   553   590   605   647   673   701   750   784 ]  % 31-H - 40-H 
-            >> 
-        >> def 
-
-        %            M1 M2 M3 M4         M1 M2 M3 M4         M1 M2 M3 M4         M1 M2 M3 M4
-        /microcaps <<
-            /numeric <<
-                /L [  5 10 23 35 ]  /M [ -1  8 18 30 ]  /Q [ -1 -1 -1 21 ]  /H [ -1 -1 -1 -1 ]
-            >>
-            /alphanumeric <<
-                /L [ -1  6 14 21 ]  /M [ -1  5 11 18 ]  /Q [ -1 -1 -1 13 ]  /H [ -1 -1 -1 -1 ]
-            >>
-            /byte <<
-                /L [ -1 -1  9 15 ]  /M [ -1 -1  7 13 ]  /Q [ -1 -1 -1  9 ]  /H [ -1 -1 -1 -1 ]
-            >> 
-            /kanji <<
-                /L [ -1 -1  6  9 ]  /M [ -1 -1  4  8 ]  /Q [ -1 -1 -1  5 ]  /H [ -1 -1 -1 -1 ]
-            >>
-        >> def
-
-        /encvals <<
-            /numeric      0
-            /alphanumeric 1
-            /byte         2
-            /kanji        3
-        >> def
-
-        /encs <<
-            /numeric      /encnumeric
-            /alphanumeric /encalphanumeric
-            /byte         /encbyte
-            /kanji        /enckanji
-        >> def
-
-        %           N      A      B      K
-        /mids  [ (0001) (0010) (0100) (1000) ] def
-        /mids <<
-           /M1 [     ()     -1     -1     -1 ]
-           /M2 [    (0)    (1)     -1     -1 ]
-           /M3 [   (00)   (01)   (10)   (11) ]
-           /M4 [  (000)  (001)  (010)  (011) ]
-           1 1 40 {2 string 10 exch cvrs mids} for
-        >> def
-
-        %            N  A  B  K
-        /cc1to9   [ 10  9  8  8 ] def
-        /cc10to26 [ 12 11 16 10 ] def
-        /cc27to40 [ 14 13 16 12 ] def
-        /cclens <<
-            /M1   [  3 -1 -1 -1 ]
-            /M2   [  4  3 -1 -1 ]
-            /M3   [  5  4  4  3 ]
-            /M4   [  6  5  5  4 ]
-             1 1  9 { 2 string 10 exch cvrs cc1to9 } for
-            10 1 26 { 2 string 10 exch cvrs cc10to26 } for            
-            27 1 40 { 2 string 10 exch cvrs cc27to40 } for
-        >> def
-
-        % Alphanumeric character to value map
-        /charmap (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:) def
-        /charvals 44 dict def
-        0 1 44 {dup charmap exch get exch charvals 3 1 roll put} for
-
-        /encnumeric {
-            /in exch def
-            /out in length 10 mul 3 idiv 1 add string def
-            /i 0 def /j 0 def {
-                i in length eq {exit} if
-                i in length 2 sub lt {
-                    (0000000000) 10 string copy
-                    dup in i 3 getinterval cvi
-                    2 10 string cvrs dup length 10 exch sub exch putinterval
-                    /i i 3 add def
-                } {
-                    i in length 2 sub eq {  % Two final digits
-                        (0000000) 7 string copy
-                        dup in i 2 getinterval cvi
-                        2 7 string cvrs dup length 7 exch sub exch putinterval
-                        /i i 2 add def
-                    } {  % One final digit
-                        (0000) 4 string copy
-                        dup in i 1 getinterval cvi
-                        2 4 string cvrs dup length 4 exch sub exch putinterval
-                        /i i 1 add def
-                    } ifelse
+    /N 0 def  /A 1 def  /B 2 def  /K 3 def
+   
+    /Nexcl <<
+       [
+           16#30 1 16#39 {} for
+       ] {-1} forall
+    >> def
+    
+    /Aexcl <<
+        [
+            16#20 16#24 16#25 16#2A 16#2B 16#2D 16#2E 16#2F 16#3A
+            16#41 1 16#5A {} for
+        ] {-1} forall
+    >> def
+    
+    /Bexcl <<
+        [
+            16#00 1 16#1F {} for
+            16#21 16#22 16#23 16#26 16#27 16#28 16#29 16#2C
+            16#3B 1 16#40 {} for
+            16#5B 1 16#7F {} for
+            16#A0 1 16#DF {} for
+        ] {-1} forall
+    >> def
+    
+    /Kexcl <<
+        [
+            16#81 1 16#9F {} for
+            16#E0 1 16#EB {} for
+        ] {-1} forall
+    >> def
+    
+    /mids [  % N  A  B  K
+      [ (0001) (0010) (0100) (1000) ]  %  1-9
+      [ (0001) (0010) (0100) (1000) ]  % 10-26
+      [ (0001) (0010) (0100) (1000) ]  % 27-40
+      [     ()   -1     -1     -1   ]  % M1
+      [    (0)    (1)   -1     -1   ]  % M2
+      [   (00)   (01)   (10)   (11) ]  % M3
+      [  (000)  (001)  (010)  (011) ]  % M4
+    ] def
+    
+    /cclens [  % N  A  B  K
+      [ 10  9  8  8 ]  %  1-9
+      [ 12 11 16 10 ]  % 10-26
+      [ 14 13 16 12 ]  % 27-40
+      [  3 -1 -1 -1 ]  % M1
+      [  4  3 -1 -1 ]  % M2
+      [  5  4  4  3 ]  % M3
+      [  6  5  5  4 ]  % M4
+    ] def
+    
+    /termlens [ 4 4 4 3 5 7 9 ] def
+    
+    % Encoding functions
+    /tobin {
+        string dup length 1 sub 0 exch 1 exch {1 index exch 48 put} for
+        dup 3 -1 roll 2 2 index length string cvrs dup length 2 index length exch sub exch putinterval
+    } bind def
+
+    % Alphanumeric character to value map
+    /charmap (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:) def
+    /charvals 44 dict def
+    0 1 44 {dup charmap exch get exch charvals 3 1 roll put} for
+
+    /encA {
+        /in exch def
+        fnc1first {  % FNC1 as %
+            /in [ in { dup -1 eq {pop 37} if } forall ] def
+        } if
+        /out in length 11 mul 2 idiv 1 add string def
+        /k 0 def /m 0 def {
+            k in length eq {exit} if
+            k in length 1 sub lt {
+                charvals in k get get 45 mul charvals in k 1 add get get add 11 tobin
+                /k k 2 add def
+            } {  % Final character
+                charvals in k get get 6 tobin
+                /k k 1 add def
+            } ifelse
+            dup out exch m exch putinterval
+            length m add /m exch def
+        } loop
+        out 0 m getinterval
+    } bind def
+    
+    /encN {
+        /in exch def
+        /out in length 10 mul 3 idiv 1 add string def
+        /k 0 def /m 0 def {
+            k in length eq {exit} if
+            k in length 2 sub lt {
+                in k 3 getinterval 0 exch {exch 10 mul 48 sub add} forall 10 tobin
+                /k k 3 add def
+            } {
+                k in length 2 sub eq {  % Two final digits
+                    in k 2 getinterval 0 exch {exch 10 mul 48 sub add} forall 7 tobin
+                    /k k 2 add def
+                } {  % One final digit
+                    in k 1 getinterval 0 exch {exch 10 mul 48 sub add} forall 4 tobin
+                    /k k 1 add def
                 } ifelse
-                dup out exch j exch putinterval
-                length j add /j exch def
+            } ifelse
+            dup out exch m exch putinterval
+            length m add /m exch def
+        } loop
+        out 0 m getinterval
+    } bind def
+    
+    /encB {
+        /in exch def
+        fnc1first {  % FNC1 as GS
+            /in [ in { dup -1 eq {pop 29} if } forall ] def
+        } if
+        /out in length 8 mul string def
+        0 1 in length 1 sub {
+            /k exch def
+            in k get cvi 8 tobin
+            out k 8 mul 3 -1 roll putinterval
+        } for
+        out
+    } bind def
+    
+    /encK {
+        /in exch def
+        /out in length 2 idiv 13 mul string def
+        /k 0 def /m 0 def {
+            k in length eq {exit} if
+            in k get 256 mul in k 1 add get add
+            dup 16#E040 lt {16#8140} {16#C140} ifelse sub
+            dup -8 bitshift 16#C0 mul exch 16#00FF and add
+            13 tobin dup out exch m exch putinterval
+            length m add /m exch def
+            /k k 2 add def
+        } loop
+        out
+    } bind def
+    
+    /encfuncs [ /encN /encA /encB /encK ] def
+    
+    /addtobits {
+        dup bits j 3 -1 roll putinterval
+        length j add /j exch def
+    } bind def
+    
+    /numNs [ msglen {0} repeat 0 ] def
+    /numAs [ msglen {0} repeat 0 ] def
+    /numBs [ msglen {0} repeat 0 ] def
+    /numKs [ msglen {0} repeat -1 ] def
+    /nextNs [ msglen {0} repeat 9999 ] def
+    /nextBs [ msglen {0} repeat 9999 ] def
+    /nextAs [ msglen {0} repeat 9999 ] def
+    /nextKs [ msglen {0} repeat 9999 ] def
+    msglen 1 sub -1 0 {
+        /i exch def
+        /barchar msg i get def
+        Kexcl barchar known {
+            nextKs i 0 put
+            numKs i numKs i 1 add get 1 add put
+        } {
+            nextKs i nextKs i 1 add get 1 add put
+        } ifelse
+        Nexcl barchar known {
+            nextNs i 0 put
+            numNs i numNs i 1 add get 1 add put
+        } {
+            nextNs i nextNs i 1 add get 1 add put
+        } ifelse
+        Bexcl barchar known {
+            nextBs i 0 put
+            numBs i numBs i 1 add get 1 add put
+        } {
+            nextBs i nextBs i 1 add get 1 add put
+        } ifelse
+        Aexcl barchar known {
+            nextAs i 0 put
+            numAs i numAs i 1 add get 1 add put
+        } {
+            nextAs i nextAs i 1 add get 1 add put
+        } ifelse
+    } for
+    /numKs [ numKs {1 add 2 idiv} forall ] def
+    
+    /KbeforeB {numK exch ver get ge nextBs numK 2 mul i add get 0 eq and} bind def
+    /KbeforeA {numK exch ver get ge nextAs numK 2 mul i add get 0 eq and} bind def
+    /KbeforeN {numK exch ver get ge nextNs numK 2 mul i add get 0 eq and} bind def
+    /KbeforeE {numK exch ver get ge numK 2 mul i add msglen eq and} bind def
+    /AbeforeK {numA exch ver get ge nextKs numA i add get 0 eq and} bind def
+    /AbeforeB {numA exch ver get ge nextBs numA i add get 0 eq and} bind def
+    /AbeforeN {numA exch ver get ge nextNs numA i add get 0 eq and} bind def
+    /AbeforeE {numA exch ver get ge numA i add msglen eq and} bind def
+    /NbeforeK {numN exch ver get ge nextKs numN i add get 0 eq and} bind def
+    /NbeforeB {numN exch ver get ge nextBs numN i add get 0 eq and} bind def
+    /NbeforeA {numN exch ver get ge nextAs numN i add get 0 eq and} bind def
+    /NbeforeE {numN exch ver get ge numN i add msglen eq and} bind def
+
+    % Encode unterminated bitsream for each version group separately
+    /msgbits [-1 -1 -1 -1 -1 -1 -1] def
+    /v1to9 0 def  /v10to26 1 def  /v27to40 2 def  /vM1 3 def  /vM2 4 def  /vM3 5 def  /vM4 6 def
+    /e 10000 def
+    [v1to9 v10to26 v27to40 vM1 vM2 vM3 vM4] {
+        /ver exch def
+    
+        % Derive optimal sequence
+        /mode -1 def /seq [] def /i 0 def {
+            i msglen ge {exit} if
+            /numK numKs i get def
+            /numB numBs i get def
+            /numA numAs i get def
+            /numN numNs i get def
+            ver vM1 eq numA 1 ge and {/seq -1 def exit} if
+            ver vM1 eq numB 1 ge and {/seq -1 def exit} if
+            ver vM1 eq numK 1 ge and {/seq -1 def exit} if
+            ver vM2 eq numB 1 ge and {/seq -1 def exit} if
+            ver vM2 eq numK 1 ge and {/seq -1 def exit} if
+            {  % common exit
+                mode -1 eq {  % Set initial mode
+                    [ 1  1  1  e  e  1  1] KbeforeA {K exit} if
+                    [ 1  1  1  e  e  1  1] KbeforeN {K exit} if
+                    [ 5  5  6  e  e  2  3] KbeforeB {K exit} if
+                    [ 1  1  1  e  e  1  1] KbeforeE {K exit} if
+                    numK 1 ge {B exit} if
+                    [ 6  7  8  e  e  3  4] AbeforeB {A exit} if
+                    [ 1  1  1  e  1  1  1] AbeforeE {A exit} if
+                    numA 1 ge {
+                        ver vM1 ne ver vM2 ne and {B} {A} ifelse exit
+                    } if
+                    [ 4  4  5  e  e  2  3] NbeforeB {N exit} if
+                    [ 1  1  1  e  e  1  1] NbeforeB {B exit} if
+                    [ 7  8  9  e  3  4  5] NbeforeA {N exit} if
+                    [ 1  1  1  e  1  1  1] NbeforeA {A exit} if
+                    numN 1 ge {N exit} if
+                    B exit
+                } if
+                mode B eq {
+                    [ 9 12 13  e  e  4  5] KbeforeB {K exit} if
+                    [ 9 10 12  e  e  4  5] KbeforeA {K exit} if
+                    [ 9 10 11  e  e  5  6] KbeforeN {K exit} if
+                    [ 4  5  6  e  e  2  3] KbeforeE {K exit} if
+                    [11 12 14  e  e  5  7] AbeforeK {A exit} if
+                    [11 15 16  e  e  6  7] AbeforeB {A exit} if
+                    [12 13 15  e  e  6  8] AbeforeN {A exit} if
+                    [ 6  7  8  e  e  3  4] AbeforeE {A exit} if
+                    [ 6  7  8  e  e  3  4] NbeforeK {N exit} if
+                    [ 6  8  9  e  e  3  4] NbeforeB {N exit} if
+                    [ 6  7  8  e  e  3  4] NbeforeA {N exit} if
+                    [ 3  4  5  e  e  2  3] NbeforeE {N exit} if
+                    B exit
+                } if
+                mode A eq {
+                    numK 1 ge {K exit} if
+                    numB 1 ge {B exit} if
+                    [13 15 17  e  5  7  9] NbeforeA {N exit} if
+                    [13 17 18  e  e  7  9] NbeforeB {N exit} if
+                    [ 7  8  9  e  3  4  5] NbeforeE {N exit} if
+                    A exit
+                } if
+                mode N eq {
+                    numK 1 ge {K exit} if
+                    numB 1 ge {B exit} if
+                    numA 1 ge {A exit} if
+                    N exit
+                } if
+                mode K eq {
+                    numB 1 ge {B exit} if
+                    numA 1 ge {A exit} if
+                    numN 1 ge {N exit} if
+                    K exit
+                } if
             } loop
-            out 0 j getinterval
-        } bind def
-
-        /encalphanumeric {
-            /in exch def
-            /out in length 11 mul 2 idiv 1 add string def
-            /i 0 def /j 0 def {
-                i in length eq {exit} if
-                i in length 1 sub lt {
-                    (00000000000) 11 string copy
-                    dup charvals in i get get 45 mul charvals in i 1 add get get add
-                    2 11 string cvrs dup length 11 exch sub exch putinterval
-                    /i i 2 add def
-                } {
-                    (000000) 6 string copy
-                    dup charvals in i get get
-                    2 6 string cvrs dup length 6 exch sub exch putinterval
-                    /i i 1 add def
-                } ifelse
-                dup out exch j exch putinterval
-                length j add /j exch def
-            } loop
-            out 0 j getinterval
-        } bind def
-
-        /encbyte {
-            /in exch def
-            /out in length 8 mul string def
-            0 1 in length 1 sub {
+            dup K eq fnc1first and {pop B} if  % No kanji with fnc1first
+            dup mode eq {  % Same mode encode directly
+                pop
+                /dat msg i mode K eq {2} {1} ifelse getinterval def
+                /seq [
+                    seq aload pop
+                    [ exch aload pop dat aload pop ]
+                ] def
+            } {  % Change mode
+                /mode exch def
+                mode K eq {K msg i numK 2 mul getinterval} if
+                mode B eq {B msg i numB getinterval} if
+                mode A eq {A msg i numA getinterval} if
+                mode N eq {N msg i numN getinterval} if
+                /dat exch def /sw exch def
+                /seq [ seq aload pop sw dat ] def
+            } ifelse
+            /i i dat length add def
+        } loop
+
+        % Encode the sequence
+        {  % common exit
+            seq -1 eq {exit} if  % Sequence not available
+            /bits 23648 string def
+            /j 0 def
+            fnc1first {(0101) addtobits} if
+            /abort false def
+            0 2 seq length 1 sub {
                 /i exch def
-                (00000000) 8 string copy
-                dup in i get cvi
-                2 8 string cvrs dup length 8 exch sub exch putinterval 
-                out i 8 mul 3 -1 roll putinterval
+                /mode seq i get def
+                mids ver get mode get addtobits
+                /cclen cclens ver get mode get def
+                /chars seq i 1 add get def
+                chars length 2 cclen exp cvi ge {  % Too many characters for cc indicator
+                    /abort true def exit
+                } if
+                chars length mode K eq {2 idiv} if cclen tobin addtobits
+                chars encfuncs mode get load exec addtobits
             } for
-            out
-        } bind def
-
-        /enckanji {
-            /in exch def
-            /out in length 2 idiv 13 mul string def
-            /i 0 def /j 0 def {
-                i in length eq {exit} if
-                in i get 256 mul in i 1 add get add
-                dup 16#E040 lt {16#8140} {16#C140} ifelse sub
-                dup -8 bitshift 16#C0 mul exch 16#00FF and add
-                (0000000000000) 13 string copy
-                dup 3 -1 roll 2 13 string cvrs dup length 13 exch sub exch putinterval
-                dup out exch j exch putinterval
-                length j add /j exch def
-                /i i 2 add def
-            } loop
-            out
-        } bind def
-
-        % Determine a compact encoding for the data
-        encoding (unset) eq {
-            /numericokay true def
-            /alphanumericokay true def
-            /kanjiokay true def
-            /byteokay true def
-            barlen 2 mod 0 ne {/kanjiokay false def} if
-            0 1 barlen 1 sub {
-                /i exch def
-                /barchar barcode i get def
-                barchar 48 lt barchar 57 gt or {/numericokay false def} if
-                charvals barchar known not {/alphanumericokay false def} if
-                i 2 mod 0 eq {
-                    barchar 16#81 lt barchar 16#9F gt or
-                    barchar 16#E0 lt barchar 16#EB gt or and {
-                        /kanjiokay false def
-                    } if
-                } if
-            } for
-            byteokay         {/encoding (byte) def} if
-            kanjiokay        {/encoding (kanji) def} if
-            alphanumericokay {/encoding (alphanumeric) def} if
-            numericokay      {/encoding (numeric) def} if
-        } if
-
-        % Determine smallest symbol version to hold given amount of data
-        /numchars barlen encoding (kanji) eq {2 idiv} if def
-        version (unset) eq {
-            /caps format (full) eq {fullcaps} {microcaps} ifelse encoding get eclevel get def
-            /i 1 def {
-                numchars caps i 1 sub get le {exit} if
-                /i i 1 add def
-            } loop
-            /version i 10 2 string cvrs def
-            format (micro) eq {
-                /version (M ) 2 string copy dup version 1 exch putinterval def
-            } if
-        } if
-
-        % Opportunistically raise the error correction level for a fit to the same symbol
-        /caps format (full) eq {fullcaps} {microcaps} ifelse encoding get def
-        /verval format (full) eq {version cvi 1 sub} {version 1 get 49 sub} ifelse def
-        eclevel (L) eq {numchars caps /M get verval get le {/eclevel (M) def} if} if
-        eclevel (M) eq {numchars caps /Q get verval get le {/eclevel (Q) def} if} if
-        eclevel (Q) eq {numchars caps /H get verval get le {/eclevel (H) def} if} if
-
-        % Set the control character data for the version
-        /mid mids version get encvals encoding get get def
-        /cclen cclens version get encvals encoding get get def
- 
-        % Create the bitstream as mode_id character_count encoded_data
-        /enc barcode encs encoding get load exec def
-        (0000000000000000) 0 cclen getinterval cclen string copy 
-        dup barlen encoding (kanji) eq {2 idiv} if cvi
-        2 cclen string cvrs dup length cclen exch sub exch putinterval 
-        /cc exch def
-        /msgbits mid length cclen add enc length add string def
-        msgbits 0 mid putinterval
-        msgbits mid length cc putinterval
-        msgbits mid length cclen add enc putinterval
-
-    } ifelse
+            abort {exit} if
+            /bits bits 0 j getinterval def
+            msgbits ver bits put
+            exit
+        } loop
+    } forall
 
     % Lookup the most appropriate symbol specification
     /metrics [
-        % format   vers  size align modules    error codewords        error correction blocks 
-        %                                      L    M    Q    H       L1 L2 M1 M2 Q1 Q2 H1 H2
-        [ (micro)  (M1)   11  98 99     36  [   2   99   99   99 ]  [  1  0 -1 -1 -1 -1 -1 -1 ] ]
-        [ (micro)  (M2)   13  98 99     80  [   5    6   99   99 ]  [  1  0  1  0 -1 -1 -1 -1 ] ]
-        [ (micro)  (M3)   15  98 99    132  [   6    8   99   99 ]  [  1  0  1  0 -1 -1 -1 -1 ] ]
-        [ (micro)  (M4)   17  98 99    192  [   8   10   14   99 ]  [  1  0  1  0  1  0 -1 -1 ] ]
-        [ (full)   (1)    21  98 99    208  [   7   10   13   17 ]  [  1  0  1  0  1  0  1  0 ] ]
-        [ (full)   (2)    25  18 99    359  [  10   16   22   28 ]  [  1  0  1  0  1  0  1  0 ] ]
-        [ (full)   (3)    29  22 99    567  [  15   26   36   44 ]  [  1  0  1  0  2  0  2  0 ] ]
-        [ (full)   (4)    33  26 99    807  [  20   36   52   64 ]  [  1  0  2  0  2  0  4  0 ] ]
-        [ (full)   (5)    37  30 99   1079  [  26   48   72   88 ]  [  1  0  2  0  2  2  2  2 ] ]
-        [ (full)   (6)    41  34 99   1383  [  36   64   96  112 ]  [  2  0  4  0  4  0  4  0 ] ]
-        [ (full)   (7)    45  22 38   1568  [  40   72  108  130 ]  [  2  0  4  0  2  4  4  1 ] ]
-        [ (full)   (8)    49  24 42   1936  [  48   88  132  156 ]  [  2  0  2  2  4  2  4  2 ] ]
-        [ (full)   (9)    53  26 46   2336  [  60  110  160  192 ]  [  2  0  3  2  4  4  4  4 ] ]
-        [ (full)   (10)   57  28 50   2768  [  72  130  192  224 ]  [  2  2  4  1  6  2  6  2 ] ]
-        [ (full)   (11)   61  30 54   3232  [  80  150  224  264 ]  [  4  0  1  4  4  4  3  8 ] ]
-        [ (full)   (12)   65  32 58   3728  [  96  176  260  308 ]  [  2  2  6  2  4  6  7  4 ] ]
-        [ (full)   (13)   69  34 62   4256  [ 104  198  288  352 ]  [  4  0  8  1  8  4 12  4 ] ]
-        [ (full)   (14)   73  26 46   4651  [ 120  216  320  384 ]  [  3  1  4  5 11  5 11  5 ] ]
-        [ (full)   (15)   77  26 48   5243  [ 132  240  360  432 ]  [  5  1  5  5  5  7 11  7 ] ]
-        [ (full)   (16)   81  26 50   5867  [ 144  280  408  480 ]  [  5  1  7  3 15  2  3 13 ] ]
-        [ (full)   (17)   85  30 54   6523  [ 168  308  448  532 ]  [  1  5 10  1  1 15  2 17 ] ]
-        [ (full)   (18)   89  30 56   7211  [ 180  338  504  588 ]  [  5  1  9  4 17  1  2 19 ] ]
-        [ (full)   (19)   93  30 58   7931  [ 196  364  546  650 ]  [  3  4  3 11 17  4  9 16 ] ]
-        [ (full)   (20)   97  34 62   8683  [ 224  416  600  700 ]  [  3  5  3 13 15  5 15 10 ] ]
-        [ (full)   (21)  101  28 50   9252  [ 224  442  644  750 ]  [  4  4 17  0 17  6 19  6 ] ]
-        [ (full)   (22)  105  26 50  10068  [ 252  476  690  816 ]  [  2  7 17  0  7 16 34  0 ] ]
-        [ (full)   (23)  109  30 54  10916  [ 270  504  750  900 ]  [  4  5  4 14 11 14 16 14 ] ]
-        [ (full)   (24)  113  28 54  11796  [ 300  560  810  960 ]  [  6  4  6 14 11 16 30  2 ] ]
-        [ (full)   (25)  117  32 58  12708  [ 312  588  870 1050 ]  [  8  4  8 13  7 22 22 13 ] ]
-        [ (full)   (26)  121  30 58  13652  [ 336  644  952 1110 ]  [ 10  2 19  4 28  6 33  4 ] ]
-        [ (full)   (27)  125  34 62  14628  [ 360  700 1020 1200 ]  [  8  4 22  3  8 26 12 28 ] ]
-        [ (full)   (28)  129  26 50  15371  [ 390  728 1050 1260 ]  [  3 10  3 23  4 31 11 31 ] ]
-        [ (full)   (29)  133  30 54  16411  [ 420  784 1140 1350 ]  [  7  7 21  7  1 37 19 26 ] ]
-        [ (full)   (30)  137  26 52  17483  [ 450  812 1200 1440 ]  [  5 10 19 10 15 25 23 25 ] ]
-        [ (full)   (31)  141  30 56  18587  [ 480  868 1290 1530 ]  [ 13  3  2 29 42  1 23 28 ] ]
-        [ (full)   (32)  145  34 60  19723  [ 510  924 1350 1620 ]  [ 17  0 10 23 10 35 19 35 ] ]
-        [ (full)   (33)  149  30 58  20891  [ 540  980 1440 1710 ]  [ 17  1 14 21 29 19 11 46 ] ]
-        [ (full)   (34)  153  34 62  22091  [ 570 1036 1530 1800 ]  [ 13  6 14 23 44  7 59  1 ] ]
-        [ (full)   (35)  157  30 54  23008  [ 570 1064 1590 1890 ]  [ 12  7 12 26 39 14 22 41 ] ]
-        [ (full)   (36)  161  24 50  24272  [ 600 1120 1680 1980 ]  [  6 14  6 34 46 10  2 64 ] ]
-        [ (full)   (37)  165  28 54  25568  [ 630 1204 1770 2100 ]  [ 17  4 29 14 49 10 24 46 ] ]
-        [ (full)   (38)  169  32 58  26896  [ 660 1260 1860 2220 ]  [  4 18 13 32 48 14 42 32 ] ]
-        [ (full)   (39)  173  26 54  28256  [ 720 1316 1950 2310 ]  [ 20  4 40  7 43 22 10 67 ] ]
-        [ (full)   (40)  177  30 58  29648  [ 750 1372 2040 2430 ]  [ 19  6 18 31 34 34 20 61 ] ]
+        % format   vers  vergrp  size align modules    error codewords        error correction blocks 
+        %                                              L    M    Q    H       L1 L2 M1 M2 Q1 Q2 H1 H2
+        [ (micro)  (M1)  vM1       11  98 99     36  [   2   99   99   99 ]  [  1  0 -1 -1 -1 -1 -1 -1 ] ]
+        [ (micro)  (M2)  vM2       13  98 99     80  [   5    6   99   99 ]  [  1  0  1  0 -1 -1 -1 -1 ] ]
+        [ (micro)  (M3)  vM3       15  98 99    132  [   6    8   99   99 ]  [  1  0  1  0 -1 -1 -1 -1 ] ]
+        [ (micro)  (M4)  vM4       17  98 99    192  [   8   10   14   99 ]  [  1  0  1  0  1  0 -1 -1 ] ]
+        [ (full)   (1)   v1to9     21  98 99    208  [   7   10   13   17 ]  [  1  0  1  0  1  0  1  0 ] ]
+        [ (full)   (2)   v1to9     25  18 99    359  [  10   16   22   28 ]  [  1  0  1  0  1  0  1  0 ] ]
+        [ (full)   (3)   v1to9     29  22 99    567  [  15   26   36   44 ]  [  1  0  1  0  2  0  2  0 ] ]
+        [ (full)   (4)   v1to9     33  26 99    807  [  20   36   52   64 ]  [  1  0  2  0  2  0  4  0 ] ]
+        [ (full)   (5)   v1to9     37  30 99   1079  [  26   48   72   88 ]  [  1  0  2  0  2  2  2  2 ] ]
+        [ (full)   (6)   v1to9     41  34 99   1383  [  36   64   96  112 ]  [  2  0  4  0  4  0  4  0 ] ]
+        [ (full)   (7)   v1to9     45  22 38   1568  [  40   72  108  130 ]  [  2  0  4  0  2  4  4  1 ] ]
+        [ (full)   (8)   v1to9     49  24 42   1936  [  48   88  132  156 ]  [  2  0  2  2  4  2  4  2 ] ]
+        [ (full)   (9)   v1to9     53  26 46   2336  [  60  110  160  192 ]  [  2  0  3  2  4  4  4  4 ] ]
+        [ (full)   (10)  v10to26   57  28 50   2768  [  72  130  192  224 ]  [  2  2  4  1  6  2  6  2 ] ]
+        [ (full)   (11)  v10to26   61  30 54   3232  [  80  150  224  264 ]  [  4  0  1  4  4  4  3  8 ] ]
+        [ (full)   (12)  v10to26   65  32 58   3728  [  96  176  260  308 ]  [  2  2  6  2  4  6  7  4 ] ]
+        [ (full)   (13)  v10to26   69  34 62   4256  [ 104  198  288  352 ]  [  4  0  8  1  8  4 12  4 ] ]
+        [ (full)   (14)  v10to26   73  26 46   4651  [ 120  216  320  384 ]  [  3  1  4  5 11  5 11  5 ] ]
+        [ (full)   (15)  v10to26   77  26 48   5243  [ 132  240  360  432 ]  [  5  1  5  5  5  7 11  7 ] ]
+        [ (full)   (16)  v10to26   81  26 50   5867  [ 144  280  408  480 ]  [  5  1  7  3 15  2  3 13 ] ]
+        [ (full)   (17)  v10to26   85  30 54   6523  [ 168  308  448  532 ]  [  1  5 10  1  1 15  2 17 ] ]
+        [ (full)   (18)  v10to26   89  30 56   7211  [ 180  338  504  588 ]  [  5  1  9  4 17  1  2 19 ] ]
+        [ (full)   (19)  v10to26   93  30 58   7931  [ 196  364  546  650 ]  [  3  4  3 11 17  4  9 16 ] ]
+        [ (full)   (20)  v10to26   97  34 62   8683  [ 224  416  600  700 ]  [  3  5  3 13 15  5 15 10 ] ]
+        [ (full)   (21)  v10to26  101  28 50   9252  [ 224  442  644  750 ]  [  4  4 17  0 17  6 19  6 ] ]
+        [ (full)   (22)  v10to26  105  26 50  10068  [ 252  476  690  816 ]  [  2  7 17  0  7 16 34  0 ] ]
+        [ (full)   (23)  v10to26  109  30 54  10916  [ 270  504  750  900 ]  [  4  5  4 14 11 14 16 14 ] ]
+        [ (full)   (24)  v10to26  113  28 54  11796  [ 300  560  810  960 ]  [  6  4  6 14 11 16 30  2 ] ]
+        [ (full)   (25)  v10to26  117  32 58  12708  [ 312  588  870 1050 ]  [  8  4  8 13  7 22 22 13 ] ]
+        [ (full)   (26)  v10to26  121  30 58  13652  [ 336  644  952 1110 ]  [ 10  2 19  4 28  6 33  4 ] ]
+        [ (full)   (27)  v27to40  125  34 62  14628  [ 360  700 1020 1200 ]  [  8  4 22  3  8 26 12 28 ] ]
+        [ (full)   (28)  v27to40  129  26 50  15371  [ 390  728 1050 1260 ]  [  3 10  3 23  4 31 11 31 ] ]
+        [ (full)   (29)  v27to40  133  30 54  16411  [ 420  784 1140 1350 ]  [  7  7 21  7  1 37 19 26 ] ]
+        [ (full)   (30)  v27to40  137  26 52  17483  [ 450  812 1200 1440 ]  [  5 10 19 10 15 25 23 25 ] ]
+        [ (full)   (31)  v27to40  141  30 56  18587  [ 480  868 1290 1530 ]  [ 13  3  2 29 42  1 23 28 ] ]
+        [ (full)   (32)  v27to40  145  34 60  19723  [ 510  924 1350 1620 ]  [ 17  0 10 23 10 35 19 35 ] ]
+        [ (full)   (33)  v27to40  149  30 58  20891  [ 540  980 1440 1710 ]  [ 17  1 14 21 29 19 11 46 ] ]
+        [ (full)   (34)  v27to40  153  34 62  22091  [ 570 1036 1530 1800 ]  [ 13  6 14 23 44  7 59  1 ] ]
+        [ (full)   (35)  v27to40  157  30 54  23008  [ 570 1064 1590 1890 ]  [ 12  7 12 26 39 14 22 41 ] ]
+        [ (full)   (36)  v27to40  161  24 50  24272  [ 600 1120 1680 1980 ]  [  6 14  6 34 46 10  2 64 ] ]
+        [ (full)   (37)  v27to40  165  28 54  25568  [ 630 1204 1770 2100 ]  [ 17  4 29 14 49 10 24 46 ] ]
+        [ (full)   (38)  v27to40  169  32 58  26896  [ 660 1260 1860 2220 ]  [  4 18 13 32 48 14 42 32 ] ]
+        [ (full)   (39)  v27to40  173  26 54  28256  [ 720 1316 1950 2310 ]  [ 20  4 40  7 43 22 10 67 ] ]
+        [ (full)   (40)  v27to40  177  30 58  29648  [ 750 1372 2040 2430 ]  [ 19  6 18 31 34 34 20 61 ] ]
     ] def
     /eclval (LMQH) eclevel search pop length exch pop exch pop def
-    /i 0 def
-    { % loop
+    0 1 43 {
+        /i exch def
         /m metrics i get def
         /frmt m 0 get def                             % Format of the symbol
         /vers m 1 get def                             % Version of symbol
-        /size m 2 get def                             % Length of side
-        /asp2 m 3 get def                             % Position of second alignment symbol
-        /asp3 m 4 get def                             % Position of third alignment symbol
-        /nmod m 5 get def                             % Number of modules
+        /vergrp m 2 get def                           % Version group
+        /size m 3 get def                             % Length of side
+        /asp2 m 4 get def                             % Position of second alignment symbol
+        /asp3 m 5 get def                             % Position of third alignment symbol
+        /nmod m 6 get def                             % Number of modules
         /ncws nmod 8 idiv def                         % Total number of codewords
         /rbit nmod 8 mod def                          % Number of remainder bits
         /lc4b false def                               % Last data codeword is 4 bits long
@@ -13074,39 +15532,43 @@
             /rbit 0 def
             /lc4b true def
         } if
-        /ecws m 6 get eclval get def                  % Number of error correction codewords
+        /ecws m 7 get eclval get def                  % Number of error correction codewords
         /dcws ncws ecws sub def                       % Number of data codewords
         /dmod dcws 8 mul lc4b {4} {0} ifelse sub def  % Number of data modules
-        /ecb1 m 7 get eclval 2 mul get def            % First error correction blocks
-        /ecb2 m 7 get eclval 2 mul 1 add get def      % Second error correction blocks
+        /ecb1 m 8 get eclval 2 mul get def            % First error correction blocks
+        /ecb2 m 8 get eclval 2 mul 1 add get def      % Second error correction blocks
         /okay true def
-        format frmt ne {/okay false def} if           % The format must match that supplied
+        format (any) ne format frmt ne and {/okay false def} if  % The format must match that supplied
+        frmt (micro) eq fnc1first and {/okay false def} if
         version (unset) ne version vers ne and {/okay false def} if  % The version must match that supplied
-        msgbits length dmod gt {/okay false def} if   % Bitstream must fit into data modules
         ecb1 -1 eq ecb2 -1 eq or {/okay false def} if % Error correction level must be valid
+        /verbits msgbits vergrp get def
+        verbits -1 eq {                               % Bitstream must be available
+            /okay false def
+        } {
+            verbits length dmod gt {/okay false def} if  % and fit into data modules
+        } ifelse
+        /term (000000000) 0 termlens vergrp get getinterval def
         okay {exit} if
-        /i i 1 add def
-    } loop
+    } for
+
+    okay not {
+        /bwipp.qrcodeNoValidSymbol (No valid symbol available) //raiseerror exec
+    } if
 
     /format frmt def
     /version vers def
+    /msgbits verbits def
     /dcpb dcws ecb1 ecb2 add idiv def                 % Base data codewords per block
     /ecpb ncws ecb1 ecb2 add idiv dcpb sub def        % Error correction codewords per block
 
     % Complete the message bits by adding the terminator, truncated if neccessary
-    /terms <<
-        /M1 (000)
-        /M2 (00000)
-        /M3 (0000000)
-        /M4 (000000000)
-    >> def
-    /term terms version known {terms version get} {(0000)} ifelse def
     /term term 0 dmod msgbits length sub term length 2 copy gt {exch} if pop getinterval def
     msgbits length term length add string
     dup 0 msgbits putinterval
     dup msgbits length term putinterval
     /msgbits exch def
-    
+
     % Expand the message bits by adding padding as necessary
     /pad dmod string def
     0 1 pad length 1 sub {pad exch 48 put} for
@@ -13599,15 +16061,21 @@
 /qrcode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER qrcode--
 
 % --BEGIN ENCODER maxicode--
+% --REQUIRES preamble raiseerror renmaximatrix--
 % --DESC: MaxiCode
 % --EXAM: [)>^03001^02996152382802^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291/1^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^029^004
 % --EXOP: mode=2 parse
 % --RNDR: renmaximatrix
+%%BeginResource: uk.co.terryburton.bwipp maxicode 0.0 2014121100 125796 124711
+%%BeginData:        564 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmaximatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /maxicode {
@@ -14169,15 +16637,21 @@
 /maxicode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER maxicode--
 
 % --BEGIN ENCODER azteccode--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Aztec Code
 % --EXAM: This is Aztec Code
 % --EXOP: format=full
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp azteccode 0.0 2014121100 173685 186101
+%%BeginData:        679 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /azteccode {
@@ -14235,30 +16709,301 @@
     % Convert from input into message bitstream
     /msgbits () def 
     format (rune) ne raw and {/msgbits barcode def} if 
-    format (rune) ne raw not and {  % Simple autoencoder from input to bitstream using byte mode only
-
-        % Determine the character count
-        /barlen barcode length def
-        barlen 31 le {
-            (00000) 5 string copy dup barlen 2 5 string cvrs
-            dup length 5 exch sub exch putinterval
-            /cc exch def
-        } {
-            (0000000000000000) 16 string copy dup barlen 31 sub 2 16 string cvrs
-            dup length 16 exch sub exch putinterval
-            /cc exch def
-        } ifelse
-        /cclen cc length def
-
-        % Create the bitstream as byte_mode_id character_count data_bytes
-        /msgbits 5 cclen add barlen 8 mul add string def
-        msgbits 0 (11111) putinterval
-        msgbits 5 cc putinterval
-        0 1 barlen 1 sub {
+    format (rune) ne raw not and {
+
+        % State key: "U"pper, "L"ower, "M"ixed, "P"unctuation, "D"igit, "B"inary
+        /U 0 def  /L 1 def  /M 2 def  /P 3 def  /D 4 def  /B 5 def
+        
+        % Special function characters
+        /lu -1 def  /ll -2 def  /lm -3 def
+        /lp -4 def  /ld -5 def  /su -6 def
+        /sp -7 def  /sb -8 def  /fl -9 def
+        /p2 -10 def /p3 -11 def /p4 -12 def /p5 -13 def
+        
+        % Character maps for each state
+        /charmaps [
+            %  U    L    M    P    D
+            [  sp   sp   sp   fl   sp ]  % 0
+            [  32   32   32   13   32 ]  % 1
+            [ (A)  (a)    1   p2  (0) ]  % 2     p2 = CR LF
+            [ (B)  (b)    2   p3  (1) ]  % 3     p3 = ". "
+            [ (C)  (c)    3   p4  (2) ]  % 4     p4 = ", "
+            [ (D)  (d)    4   p5  (3) ]  % 5     p5 = ": "
+            [ (E)  (e)    5  (!)  (4) ]  % 6
+            [ (F)  (f)    6  (")  (5) ]  % 7
+            [ (G)  (g)    7  (#)  (6) ]  % 8
+            [ (H)  (h)    8  ($)  (7) ]  % 9
+            [ (I)  (i)    9  (%)  (8) ]  % 10
+            [ (J)  (j)   10  (&)  (9) ]  % 11
+            [ (K)  (k)   11  (')  (,) ]  % 12
+            [ (L)  (l)   12   40  (.) ]  % 13
+            [ (M)  (m)   13   41   lu ]  % 14
+            [ (N)  (n)   27  (*)   su ]  % 15
+            [ (O)  (o)   28  (+)  -99 ]  % 16
+            [ (P)  (p)   29  (,)  -99 ]  % 17
+            [ (Q)  (q)   30  (-)  -99 ]  % 18
+            [ (R)  (r)   31  (.)  -99 ]  % 19
+            [ (S)  (s)  (@)  (/)  -99 ]  % 20
+            [ (T)  (t)   92  (:)  -99 ]  % 21
+            [ (U)  (u)  (^)  (;)  -99 ]  % 22
+            [ (V)  (v)  (_)  (<)  -99 ]  % 23
+            [ (W)  (w)  (`)  (=)  -99 ]  % 24
+            [ (X)  (x)  (|)  (>)  -99 ]  % 25
+            [ (Y)  (y)  (~)  (?)  -99 ]  % 26
+            [ (Z)  (z)  127  ([)  -99 ]  % 27
+            [  ll   su   ll  (])  -99 ]  % 28
+            [  lm   lm   lu  ({)  -99 ]  % 29
+            [  ld   ld   lp  (})  -99 ]  % 30
+            [  sb   sb   sb   lu  -99 ]  % 31
+        ] def 
+        
+        % Invert charmaps to give character to value maps for each state
+        /charvals [ 32 dict 32 dict 32 dict 32 dict 16 dict ] def
+        0 1 charmaps length 1 sub {
             /i exch def
-            (00000000) 8 string copy dup barcode i get cvi 2 8 string cvrs dup length 8 exch sub exch putinterval 
-            msgbits 5 cclen add i 8 mul add 3 -1 roll putinterval
+            /encs charmaps i get def
+            0 1 4 {
+                /j exch def
+                encs j get dup type /stringtype eq {0 get} if  % convert string to ASCII if required
+                charvals j get exch i put 
+            } for
         } for
+        
+        % Punctuation compression
+        /pcomp <<
+            <0d0a> p2   % CR LF
+            (. )   p3
+            (, )   p4
+            (: )   p5
+        >> def
+        
+        /e 10000 def  % "Empty"
+        
+        /latlen [  % Bit length of latch between states
+        % To:  U  L  M  P  D  B      From
+            [  0  5  5 10  5 10 ]  % U
+            [  9  0  5 10  5 10 ]  % L
+            [  5  5  0  5 10 10 ]  % M
+            [  5 10 10  0 10 15 ]  % P
+            [  4  9  9 14  0 14 ]  % D
+            [  0  0  0  0  0  0 ]  % B
+        ] def
+
+        /latseq [  % Latch sequences between states
+        % To: U       L       M       P          D       B          From
+            [ []      [ll]    [lm]    [lm lp]    [ld]    [sb]    ]  % U
+            [ [ld lu] []      [lm]    [lm lp]    [ld]    [sb]    ]  % L
+            [ [lu]    [ll]    []      [lp]       [lu ld] [sb]    ]  % M
+            [ [lu]    [lu ll] [lu lm] []         [lu ld] [lu sb] ]  % P
+            [ [lu]    [lu ll] [lu lm] [lu lm lp] []      [lu sb] ]  % D
+            [ [lu]    [ll]    [lm]    []         []      []      ]  % B
+        ] def
+
+        /shftlen [  % Bit length of shift to state
+        % To:  U  L  M  P  D      From
+            [  e  e  e  5  e ]  % U
+            [  5  e  e  5  e ]  % L
+            [  e  e  e  5  e ]  % M
+            [  e  e  e  e  e ]  % P
+            [  4  e  e  4  e ]  % D
+        ] def
+        
+        %            U   L   M   P   D   B
+        /charsize [  5   5   5   5   4   8 ] def
+        
+        %          U  L  M  P  D  B
+        /curlen [  0  e  e  e  e  e ] def
+        /curseq [ [] [] [] [] [] [] ] def
+        
+        /backto U def  % U
+        /lastchar () def
+        
+        % Derive the optimal sequences ending in each state
+        barcode {
+        
+            /char exch def
+          
+            % Check for optimisations in the current sequences by latching from x to y
+            {  % loop
+                /imp false def
+                [ U L M P D B ] {
+                    /x exch def
+                    [ U L M P D B ] {
+                        /y exch def
+                        x B ne y backto eq or {  % Only B -> backto
+                            /cost curlen x get latlen x get y get add def
+                            cost curlen y get lt {
+                                curlen y cost put
+                                curseq y [
+                                    curseq x get aload pop
+                                    latseq x get y get aload pop
+                                ] put
+                                y B eq {  % Set backto to previous state
+                                    /backto x P eq x D eq or {U} {x} ifelse def
+                                } if
+                                /imp true def
+                            } if
+                        } if
+                    } forall
+                } forall
+                imp not {exit} if  % Repeat unless no improvement
+            } loop
+
+            % Determine optimal next sequences for each valid encoding 
+            /nxtlen [ e e e e e e ] def 
+            /nxtseq 6 array def
+          
+            [ U L M P D B ] {
+                /x exch def
+            
+                { % loop for common exit
+            
+                    % Skip states that cannot encode character
+                    x B ne {charvals x get char known not {exit} if} if
+              
+                    % Extend directly
+                    /cost curlen x get charsize x get add def
+                    cost nxtlen x get lt {
+                        nxtlen x cost put
+                        nxtseq x [ curseq x get aload pop char ] put
+                    } if
+              
+                    % Optimise for direct shifts from y to x 
+                    x B eq {exit} if  % B is treated as a latch
+                    [ U L M P D ] {
+                        /y exch def
+                        x y ne {
+                            /cost curlen y get shftlen y get x get add charsize x get add def
+                            cost nxtlen y get lt {
+                                nxtlen y cost put
+                                nxtseq y [
+                                    curseq y get aload pop
+                                    x U eq {su} {sp} ifelse
+                                    char
+                                ] put
+                            } if
+                        } if
+                    } forall
+              
+                    exit
+                } loop
+            
+            } forall
+          
+            % Optimise using P compression
+            lastchar () ne {
+                /pchars 2 string dup 0 lastchar put dup 1 char put def
+                pcomp pchars known {
+                    curlen P get nxtlen P get lt {
+                        nxtlen P curlen P get put
+                        nxtseq P [ curseq P get aload pop pop pcomp pchars get ] put
+                    } if
+                } if
+            } if 
+          
+            % Account for binary extension for 32 or more bytes
+            /numbytes 0 def
+            nxtseq B get {
+                sb eq {0} {numbytes 1 add} ifelse /numbytes exch def
+            } forall
+            numbytes 32 eq {nxtlen B nxtlen B get 11 add put} if
+          
+            /curlen nxtlen def
+            /curseq nxtseq def
+            /lastchar char def
+          
+        } forall
+        
+        % Select the optimal sequence
+        /minseq e def
+        [ U L M P D B ] {
+            /i exch def
+            curlen i get minseq lt {
+                /minseq curlen i get def
+                /seq curseq i get def
+            } if
+        } forall
+        
+        % Encoding functions
+        /tobin {
+            string dup length 1 sub 0 exch 1 exch {1 index exch 48 put} for
+            dup 3 -1 roll 2 2 index length string cvrs dup length 2 index length exch sub exch putinterval 
+        } bind def
+        /encu {charvals U get exch get 5 tobin} bind def
+        /encl {charvals L get exch get 5 tobin} bind def
+        /encm {charvals M get exch get 5 tobin} bind def
+        /encp {charvals P get exch get 5 tobin} bind def
+        /encd {charvals D get exch get 4 tobin} bind def
+        /encfuncs [ /encu /encl /encm /encp /encd ] def
+        /addtomsgbits {
+            /v exch def
+            msgbits j v putinterval
+            /j j v length add def
+        } bind def
+        
+        % Encode the sequence
+        /state U def
+        /msgbits minseq string def
+        /i 0 def /j 0 def {
+            i seq length ge {exit} if
+          
+            state B ne {
+          
+                /char seq i get def
+            
+                % Encode character
+                char encfuncs state get load exec addtomsgbits
+                /i i 1 add def
+            
+                % Encode shifted next character
+                char su eq char sp eq or {
+                    seq i get char su eq {encu} {encp} ifelse addtomsgbits
+                    /i i 1 add def
+                } if
+            
+                % Latches to new state
+                char lu eq {/state U def} if
+                char ll eq {/state L def} if
+                char lm eq {/state M def} if
+                char lp eq {/state P def} if
+                char ld eq {/state D def} if
+                char sb eq {/state B def} if
+            
+            } {  % Binary
+          
+                % Find number of bytes before latch or end
+                /numbytes 0 def {
+                    i numbytes add seq length ge {exit} if
+                    seq i numbytes add get 0 lt {exit} if 
+                    /numbytes numbytes 1 add def
+                } loop
+            
+                % Encode length
+                numbytes 31 le {
+                    numbytes 5 tobin addtomsgbits
+                } {
+                    0 5 tobin addtomsgbits
+                    numbytes 31 sub 11 tobin addtomsgbits
+                } ifelse
+            
+                % Encode bytes
+                numbytes {
+                    seq i get 8 tobin addtomsgbits 
+                    /i i 1 add def
+                } repeat
+            
+                % Return to previous state as indicated
+                i seq length lt {
+                    /char seq i get def
+                    /i i 1 add def
+                    char lu eq {/state U def} if
+                    char ll eq {/state L def} if
+                    char lm eq {/state M def} if
+                } if
+            
+            } ifelse
+          
+        } loop
 
     } if
 
@@ -14583,15 +17328,21 @@
 /azteccode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER azteccode--
 
 % --BEGIN ENCODER codeone--
+% --REQUIRES preamble raiseerror renmatrix--
 % --DESC: Code One
 % --EXAM: Code One
 % --EXOP: version=B
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp codeone 0.0 2014121100 104659 104025
+%%BeginData:        328 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 begin
 /codeone {
@@ -14917,16 +17668,21 @@
 /codeone dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER codeone--
 
 % --BEGIN ENCODER gs1-cc--
-% --REQUIRES micropdf417 pdf417--
+% --REQUIRES preamble raiseerror renmatrix micropdf417 pdf417--
 % --DESC: GS1 Composite 2D Component
 % --EXAM: (01)95012345678903(3103)000123
 % --EXOP: ccversion=b cccolumns=4
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp gs1-cc 0.0 2014121100 208010 203774
+%%BeginData:        650 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 dup /pdf417 dup /uk.co.terryburton.bwipp findresource put
 dup /micropdf417 dup /uk.co.terryburton.bwipp findresource put
@@ -15574,17 +18330,21 @@
 /gs1-cc dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER gs1-cc--
 
 % --BEGIN ENCODER ean13composite--
-% --REQUIRES ean13 micropdf417 pdf417 gs1-cc--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear renmatrix ean5 ean2 ean13 micropdf417 pdf417 gs1-cc--
 % --DESC: EAN-13 Composite
 % --EXAM: 2112345678900|(99)1234-abcd
 % --EXOP: includetext
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp ean13composite 0.0 2014121100 84954 88322
+%%BeginData:         72 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
-2 dict
+1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /ean13 dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -15654,17 +18414,21 @@
 /ean13composite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean13composite--
 
 % --BEGIN ENCODER ean8composite--
-% --REQUIRES ean8 micropdf417 pdf417 gs1-cc--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear renmatrix ean5 ean2 ean8 micropdf417 pdf417 gs1-cc--
 % --DESC: EAN-8 Composite
 % --EXAM: 02345673|(21)A12345678
 % --EXOP: includetext
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp ean8composite 0.0 2014121100 88815 88768
+%%BeginData:         75 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
-2 dict
+1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /ean8 dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -15737,17 +18501,21 @@
 /ean8composite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER ean8composite--
 
 % --BEGIN ENCODER upcacomposite--
-% --REQUIRES upca micropdf417 pdf417 gs1-cc--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear renmatrix ean5 ean2 upca micropdf417 pdf417 gs1-cc--
 % --DESC: UPC-A Composite
 % --EXAM: 416000336108|(99)1234-abcd
 % --EXOP: includetext
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp upcacomposite 0.0 2014121100 84932 88301
+%%BeginData:         72 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /upca dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -15817,17 +18585,21 @@
 /upcacomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER upcacomposite--
 
 % --BEGIN ENCODER upcecomposite--
-% --REQUIRES upce micropdf417 pdf417 gs1-cc--
-% --SUGGESTS ean5 ean2--
+% --REQUIRES preamble raiseerror renlinear renmatrix ean5 ean2 upce micropdf417 pdf417 gs1-cc--
 % --DESC: UPC-E Composite
 % --EXAM: 00123457|(15)021231
 % --EXOP: includetext
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp upcecomposite 0.0 2014121100 85886 92764
+%%BeginData:         87 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /upce dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -15912,16 +18684,21 @@
 /upcecomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER upcecomposite--
 
 % --BEGIN ENCODER databaromnicomposite--
-% --REQUIRES databaromni micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Omnidirectional Composite
 % --EXAM: (01)03612345678904|(11)990102
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databaromnicomposite 0.0 2014121100 97855 88807
+%%BeginData:        100 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databaromni dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -16019,16 +18796,21 @@
 /databaromnicomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databaromnicomposite--
 
 % --BEGIN ENCODER databarstackedcomposite--
-% --REQUIRES databaromni databarstacked micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni databarstacked micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Stacked Composite
 % --EXAM: (01)03412345678900|(17)010200
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarstackedcomposite 0.0 2014121100 87821 90984
+%%BeginData:         96 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databarstacked dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
@@ -16122,16 +18904,21 @@
 /databarstackedcomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarstackedcomposite--
 
 % --BEGIN ENCODER databarstackedomnicomposite--
-% --REQUIRES databaromni databarstackedomni micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni databarstackedomni micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Stacked Omnidirectional Composite
 % --EXAM: (01)03612345678904|(11)990102
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarstackedomnicomposite 0.0 2014121100 87897 90952
+%%BeginData:         96 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databarstackedomni dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
@@ -16225,16 +19012,21 @@
 /databarstackedomnicomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarstackedomnicomposite--
 
 % --BEGIN ENCODER databartruncatedcomposite--
-% --REQUIRES databaromni databartruncated micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databaromni databartruncated micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Truncated Composite
 % --EXAM: (01)03612345678904|(11)990102
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databartruncatedcomposite 0.0 2014121100 88891 91934
+%%BeginData:        100 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databartruncated dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -16332,16 +19124,21 @@
 /databartruncatedcomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databartruncatedcomposite--
 
 % --BEGIN ENCODER databarlimitedcomposite--
-% --REQUIRES databarlimited micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databarlimited micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Limited Composite
 % --EXAM: (01)03512345678907|(21)abcdefghijklmnopqrstuv
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarlimitedcomposite 0.0 2014121100 81640 81749
+%%BeginData:         79 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databarlimited dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -16418,16 +19215,21 @@
 /databarlimitedcomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarlimitedcomposite--
 
 % --BEGIN ENCODER databarexpandedcomposite--
-% --REQUIRES databarexpanded micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databarexpanded micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Expanded Composite
 % --EXAM: (01)93712345678904(3103)001234|(91)1A2B3C4D5E
 % --EXOP:
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp databarexpandedcomposite 0.0 2014121100 84742 88135
+%%BeginData:         98 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databarexpanded dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -16523,16 +19325,21 @@
 /databarexpandedcomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarexpandedcomposite--
 
 % --BEGIN ENCODER databarexpandedstackedcomposite--
-% --REQUIRES databarexpanded databarexpandedstacked micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix databarexpanded databarexpandedstacked micropdf417 pdf417 gs1-cc--
 % --DESC: GS1 DataBar Expanded Stacked Composite
 % --EXAM: (01)00012345678905(10)ABCDEF|(21)12345678
 % --EXOP: segments=4 
 % --RNDR: renmatrix renlinear
+%%BeginResource: uk.co.terryburton.bwipp databarexpandedstackedcomposite 0.0 2014121100 87600 90640
+%%BeginData:         95 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /databarexpandedstacked dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
@@ -16625,16 +19432,21 @@
 /databarexpandedstackedcomposite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER databarexpandedstackedcomposite--
 
 % --BEGIN ENCODER gs1-128composite--
-% --REQUIRES code128 gs1-128 micropdf417 pdf417 gs1-cc--
+% --REQUIRES preamble raiseerror renlinear renmatrix code128 gs1-128 micropdf417 pdf417 gs1-cc--
 % --DESC: GS1-128 Composite
 % --EXAM: (00)030123456789012340|(02)13012345678909(37)24(10)1234567ABCDEFG
 % --EXOP: ccversion=c
 % --RNDR: renlinear renmatrix
+%%BeginResource: uk.co.terryburton.bwipp gs1-128composite 0.0 2014121100 92047 87940
+%%BeginData:        100 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 2 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-128 dup /uk.co.terryburton.bwipp findresource put
 dup /gs1-cc dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
@@ -16732,16 +19544,21 @@
 /gs1-128composite dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER gs1-128composite--
 
 % --BEGIN ENCODER gs1datamatrix--
-% --REQUIRES datamatrix--
+% --REQUIRES preamble raiseerror renmatrix datamatrix--
 % --DESC: GS1 Data Matrix
 % --EXAM: (01)03453120000011(17)120508(10)ABCD1234(410)9501101020917
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp gs1datamatrix 0.0 2014121100 76851 79937
+%%BeginData:        134 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
 dup /datamatrix dup /uk.co.terryburton.bwipp findresource put
 begin
@@ -16873,32 +19690,32 @@
 /gs1datamatrix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER gs1datamatrix--
 
-% --BEGIN ENCODER hibccode39--
-% --REQUIRES code39--
-% --DESC: HIBC Code 39
-% --EXAM: A123BJC5D6E71
-% --EXOP: includetext
-% --RNDR: renlinear
+% --BEGIN ENCODER gs1qrcode--
+% --REQUIRES preamble raiseerror renmatrix qrcode--
+% --DESC: GS1 QR Code
+% --EXAM: (01)03453120000011(8200)http://www.abc.net(10)ABCD1234(410)9501101020917
+% --EXOP:
+% --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp gs1qrcode 0.0 2014121100 76691 83197
+%%BeginData:        133 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
-dup /renlinear dup /uk.co.terryburton.bwipp findresource put
-dup /code39 dup /uk.co.terryburton.bwipp findresource put
+dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
+dup /qrcode dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibccode39 {
-
-    20 dict begin                 % Confine variables to local scope
-
-    /options exch def       % We are given an option string
-    /barcode exch def       % We are given a barcode string
+/gs1qrcode {
+
+    20 dict begin            % Confine variables to local scope
+
+    /options exch def  % We are given an option string
+    /barcode exch def  % We are given a barcode string
 
     /dontdraw false def
-    /textfont /Courier def
-    /textsize 10 def
-    /textyoffset -7 def
-    /textxoffset 0 def
-
+ 
     % Parse the input options
     options type /stringtype eq {
         1 dict begin
@@ -16910,68 +19727,133 @@
     } if
     options {def} forall
 
-    /textfont textfont cvlit def
-    /textsize textsize cvr def
-    /textyoffset textyoffset cvr def
-    /textxoffset textxoffset cvr def
-
-    /barlen barcode length def
-
-    /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
-
-    /barcode barlen 2 add string dup 1 barcode putinterval def
-    barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
+    % Expand ordinals of the form ^NNN to ASCII
+    /expand {
+        /in exch def
+        /out in length string def
+        /j 0 def
+        in
+        { % loop
+            (^) search {
+                dup out exch j exch putinterval
+                length j add 1 add /j exch def
+                pop
+                dup 0 3 getinterval cvi out exch j 1 sub exch put
+                dup length 3 sub 3 exch getinterval
+            } {
+                dup out exch j exch putinterval
+                length j add /j exch def
+                out 0 j getinterval exit
+            } ifelse 
+        } loop
+    } bind def
+    
+    % Parse out AIs
+    /ais [] def
+    /aival 2 dict def
+    barcode dup length 1 sub 1 exch getinterval
+    {  % loop
+        dup () eq {exit} if
+        (\)) search pop
+        exch pop
+        exch (\() search {
+            exch pop exch 3 1 roll 
+        } { 
+            () 3 1 roll
+        } ifelse
+        [ ais aload pop counttomark 2 add index ] /ais exch def
+        aival 3 1 roll expand put
+    } loop
+    pop
+
+    % Pre-defined fixed length data field AIs
+    % any AI whose prefix is not included in this table must be
+    % terminated with "FNC1", even if it's fixed length
+    /aifixed 23 dict def
+    [
+        0 1 4 {} for
+    ] {
+        (00) 2 string copy dup dup 1 5 -1 roll 48 add put aifixed 3 1 roll put
+    } forall
+    [
+        11 1 20 {} for
+        23
+        31 1 36 {} for
+        41
+    ] {
+        10 2 string cvrs dup aifixed 3 1 roll put
+    } forall
+
+    % Create the qrcode data 
+    /fnc1 -1 def
+    /qrc [ fnc1 ] def
+    0 1 ais length 1 sub {
         /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
+        /ai ais i get def
+        /val aival ai get def
+        qrc length ai length add val length add array
+        dup 0 qrc putinterval
+        dup qrc length ai [ exch {} forall ] putinterval
+        dup qrc length ai length add val [ exch {} forall ] putinterval
+        /qrc exch def
+        i ais length 1 sub ne aifixed ai 0 2 getinterval known not and {  % Append FNC1
+            qrc length 1 add array
+            dup 0 qrc putinterval
+            dup qrc length fnc1 put
+            /qrc exch def
+        } if
     } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    /text barlen 4 add string def
-    text 0 42 put
-    text 1 barcode putinterval
-    text barlen 2 add barcode barlen 1 add get dup 32 eq {pop 95} if put
-    text barlen 3 add 42 put
-
-    % Get the result of encoding with code39
+
+    % Compose input to qrcode
+    /barcode qrc length 1 add 5 mul string def
+    /i 0 def /j 0 def {
+        i qrc length eq {exit} if
+        qrc i get dup fnc1 eq {
+            pop barcode j (^FNC1) putinterval
+            /j j 4 add def
+        } {
+            barcode exch j exch put
+        } ifelse
+        /i i 1 add def
+        /j j 1 add def
+    } loop
+    /barcode barcode 0 j getinterval def
+
+    % Get the result of encoding with qrcode
     options (dontdraw) true put
-    options (includecheck) false put
-    /args barcode options //code39 exec def
-
-    args (txt) [ [text textxoffset textyoffset textfont textsize] ] put
-    args (textxalign) (center) put
+    options (parsefnc) true put
+    /args barcode options //qrcode exec def
+
     args (opt) options put
     args
  
-    dontdraw not //renlinear if
-
+    dontdraw not //renmatrix if
+ 
     end
 
 } bind def
-/hibccode39 dup load /uk.co.terryburton.bwipp defineresource pop
+/gs1qrcode dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibccode39--
-
-% --BEGIN ENCODER hibccode128--
-% --REQUIRES code128--
-% --DESC: HIBC Code 128
+%%EndData
+%%EndResource
+% --END ENCODER gs1qrcode--
+
+% --BEGIN ENCODER hibccode39--
+% --REQUIRES preamble raiseerror renlinear code39--
+% --DESC: HIBC Code 39
 % --EXAM: A123BJC5D6E71
 % --EXOP: includetext
 % --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp hibccode39 0.0 2014121100 64068 67295
+%%BeginData:         92 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renlinear dup /uk.co.terryburton.bwipp findresource put
-dup /code128 dup /uk.co.terryburton.bwipp findresource put
+dup /code39 dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibccode128 {
+/hibccode39 {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -16983,6 +19865,7 @@
     /textsize 10 def
     /textyoffset -7 def
     /textxoffset 0 def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17000,24 +19883,36 @@
     /textyoffset textyoffset cvr def
     /textxoffset textxoffset cvr def
 
-    /barlen barcode length def
-
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibccode39badCharacter (HIBC Code 39 must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibccode39badCheckDigit (Incorrect HIBC Code 39 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
+    barcode barlen 1 add barchars checksum get put
 
     /text barlen 4 add string def
     text 0 42 put
@@ -17025,9 +19920,11 @@
     text barlen 2 add barcode barlen 1 add get dup 32 eq {pop 95} if put
     text barlen 3 add 42 put
 
-    % Get the result of encoding with code128
+    % Get the result of encoding with code39
     options (dontdraw) true put
-    /args barcode options //code128 exec def
+    options (includecheck) false put
+    options (validatecheck) false put
+    /args barcode options //code39 exec def
 
     args (txt) [ [text textxoffset textyoffset textfont textsize] ] put
     args (textxalign) (center) put
@@ -17039,23 +19936,28 @@
     end
 
 } bind def
-/hibccode128 dup load /uk.co.terryburton.bwipp defineresource pop
+/hibccode39 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibccode128--
-
-% --BEGIN ENCODER hibcdatamatrix--
-% --REQUIRES datamatrix--
-% --DESC: HIBC Data Matrix
+%%EndData
+%%EndResource
+% --END ENCODER hibccode39--
+
+% --BEGIN ENCODER hibccode128--
+% --REQUIRES preamble raiseerror renlinear code128--
+% --DESC: HIBC Code 128
 % --EXAM: A123BJC5D6E71
-% --EXOP:
-% --RNDR: renmatrix
+% --EXOP: includetext
+% --RNDR: renlinear
+%%BeginResource: uk.co.terryburton.bwipp hibccode128 0.0 2014121100 63971 67258
+%%BeginData:         91 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
-dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
-dup /datamatrix dup /uk.co.terryburton.bwipp findresource put
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
+dup /renlinear dup /uk.co.terryburton.bwipp findresource put
+dup /code128 dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibcdatamatrix {
+/hibccode128 {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -17063,6 +19965,11 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
+    /textfont /Courier def
+    /textsize 10 def
+    /textyoffset -7 def
+    /textxoffset 0 def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17075,54 +19982,85 @@
     } if
     options {def} forall
 
-    /barlen barcode length def
-
+    /textfont textfont cvlit def
+    /textsize textsize cvr def
+    /textyoffset textyoffset cvr def
+    /textxoffset textxoffset cvr def
+
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibccode128badCharacter (HIBC Code 128 must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibccode128badCheckDigit (Incorrect HIBC Code 128 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    % Get the result of encoding with datamatrix
+    barcode barlen 1 add barchars checksum get put
+
+    /text barlen 4 add string def
+    text 0 42 put
+    text 1 barcode putinterval
+    text barlen 2 add barcode barlen 1 add get dup 32 eq {pop 95} if put
+    text barlen 3 add 42 put
+
+    % Get the result of encoding with code128
     options (dontdraw) true put
-    /args barcode options //datamatrix exec def
-
+    options (validatecheck) false put
+    /args barcode options //code128 exec def
+
+    args (txt) [ [text textxoffset textyoffset textfont textsize] ] put
+    args (textxalign) (center) put
     args (opt) options put
     args
  
-    dontdraw not //renmatrix if
+    dontdraw not //renlinear if
 
     end
 
 } bind def
-/hibcdatamatrix dup load /uk.co.terryburton.bwipp defineresource pop
+/hibccode128 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibcdatamatrix--
-
-% --BEGIN ENCODER hibcpdf417--
-% --REQUIRES pdf417--
-% --DESC: HIBC PDF417
+%%EndData
+%%EndResource
+% --END ENCODER hibccode128--
+
+% --BEGIN ENCODER hibcdatamatrix--
+% --REQUIRES preamble raiseerror renmatrix datamatrix--
+% --DESC: HIBC Data Matrix
 % --EXAM: A123BJC5D6E71
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp hibcdatamatrix 0.0 2014121100 62602 69050
+%%BeginData:         74 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
-dup /pdf417 dup /uk.co.terryburton.bwipp findresource put
+dup /datamatrix dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibcpdf417 {
+/hibcdatamatrix {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -17130,7 +20068,7 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
-    /columns 2 def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17143,31 +20081,41 @@
     } if
     options {def} forall
 
-    /columns columns cvi def
-
-    /barlen barcode length def
-
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibcdatamatrixBadCharacter (HIBC Data Matrix must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibcdatamatrixBadCheckDigit (Incorrect HIBC Data Matrix check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    % Get the result of encoding with pdf417
+    barcode barlen 1 add barchars checksum get put
+
+    % Get the result of encoding with datamatrix
     options (dontdraw) true put
-    options (columns) columns put
-    /args barcode options //pdf417 exec def
+    options (validatecheck) false put
+    /args barcode options //datamatrix exec def
 
     args (opt) options put
     args
@@ -17177,23 +20125,28 @@
     end
 
 } bind def
-/hibcpdf417 dup load /uk.co.terryburton.bwipp defineresource pop
+/hibcdatamatrix dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibcpdf417--
-
-% --BEGIN ENCODER hibcmicropdf417--
-% --REQUIRES micropdf417--
-% --DESC: HIBC MicroPDF417
+%%EndData
+%%EndResource
+% --END ENCODER hibcdatamatrix--
+
+% --BEGIN ENCODER hibcpdf417--
+% --REQUIRES preamble raiseerror renmatrix pdf417--
+% --DESC: HIBC PDF417
 % --EXAM: A123BJC5D6E71
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp hibcpdf417 0.0 2014121100 61835 65021
+%%BeginData:         78 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
-dup /micropdf417 dup /uk.co.terryburton.bwipp findresource put
+dup /pdf417 dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibcmicropdf417 {
+/hibcpdf417 {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -17202,6 +20155,7 @@
 
     /dontdraw false def
     /columns 2 def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17216,29 +20170,42 @@
 
     /columns columns cvi def
 
-    /barlen barcode length def
-
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibcpdf417BadCharacter (HIBC PDF417 must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibcpdf417BadCheckDigit (Incorrect HIBC PDF417 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    % Get the result of encoding with micropdf417
+    barcode barlen 1 add barchars checksum get put
+
+    % Get the result of encoding with pdf417
     options (dontdraw) true put
     options (columns) columns put
-    /args barcode options //micropdf417 exec def
+    options (validatecheck) false put
+    /args barcode options //pdf417 exec def
 
     args (opt) options put
     args
@@ -17248,23 +20215,28 @@
     end
 
 } bind def
-/hibcmicropdf417 dup load /uk.co.terryburton.bwipp defineresource pop
+/hibcpdf417 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibcmicropdf417--
-
-% --BEGIN ENCODER hibcqrcode--
-% --REQUIRES qrcode--
-% --DESC: HIBC QR Code
+%%EndData
+%%EndResource
+% --END ENCODER hibcpdf417--
+
+% --BEGIN ENCODER hibcmicropdf417--
+% --REQUIRES preamble raiseerror renmatrix micropdf417--
+% --DESC: HIBC MicroPDF417
 % --EXAM: A123BJC5D6E71
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp hibcmicropdf417 0.0 2014121100 61885 64952
+%%BeginData:         78 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
-dup /qrcode dup /uk.co.terryburton.bwipp findresource put
+dup /micropdf417 dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibcqrcode {
+/hibcmicropdf417 {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -17272,6 +20244,8 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
+    /columns 2 def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17284,28 +20258,44 @@
     } if
     options {def} forall
 
-    /barlen barcode length def
-
+    /columns columns cvi def
+
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibcmicropdf417BadCharacter (HIBC MicroPDF417 must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibcmicropdf417BadCheckDigit (Incorrect HIBC MicroPDF417 check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    % Get the result of encoding with qrcode
+    barcode barlen 1 add barchars checksum get put
+
+    % Get the result of encoding with micropdf417
     options (dontdraw) true put
-    /args barcode options //qrcode exec def
+    options (columns) columns put
+    options (validatecheck) false put
+    /args barcode options //micropdf417 exec def
 
     args (opt) options put
     args
@@ -17315,23 +20305,28 @@
     end
 
 } bind def
-/hibcqrcode dup load /uk.co.terryburton.bwipp defineresource pop
+/hibcmicropdf417 dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
-% --END ENCODER hibcqrcode--
-
-% --BEGIN ENCODER hibccodablockf--
-% --REQUIRES codablockf--
-% --DESC: HIBC Codablock F
+%%EndData
+%%EndResource
+% --END ENCODER hibcmicropdf417--
+
+% --BEGIN ENCODER hibcqrcode--
+% --REQUIRES preamble raiseerror renmatrix qrcode--
+% --DESC: HIBC QR Code
 % --EXAM: A123BJC5D6E71
 % --EXOP:
 % --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp hibcqrcode 0.0 2014121100 65786 68742
+%%BeginData:         74 ASCII Lines
 /setpacking where {pop currentpacking true setpacking} if
 1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
 dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
-dup /codablockf dup /uk.co.terryburton.bwipp findresource put
+dup /qrcode dup /uk.co.terryburton.bwipp findresource put
 begin
-/hibccodablockf {
+/hibcqrcode {
 
     20 dict begin                 % Confine variables to local scope
 
@@ -17339,6 +20334,7 @@
     /barcode exch def       % We are given a barcode string
 
     /dontdraw false def
+    /validatecheck false def
 
     % Parse the input options
     options type /stringtype eq {
@@ -17351,28 +20347,41 @@
     } if
     options {def} forall
 
-    /barlen barcode length def
-
+    % Create a string of the available characters
     /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.hibcqrcodeBadCharacter (HIBC QR Code must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibcqrcodeBadCheckDigit (Incorrect HIBC QR Code check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
 
     /barcode barlen 2 add string dup 1 barcode putinterval def
     barcode 0 43 put
-
-    /checksum 0 def
-    0 1 barlen {
-        /i exch def
-        % Lookup the encoding for the each barcode character
-        barcode i 1 getinterval barchars exch search
-        pop                                  % Discard true leaving pre
-        length /indx exch def                % indx is the length of pre
-        pop pop                              % Discard seek and post
-        /checksum checksum indx add def
-    } for
-    barcode barlen 1 add barchars checksum 43 mod get put
-
-    % Get the result of encoding with codablockf
+    barcode barlen 1 add barchars checksum get put
+
+    % Get the result of encoding with qrcode
     options (dontdraw) true put
-    /args barcode options //codablockf exec def
+    options (validatecheck) false put
+    /args barcode options //qrcode exec def
 
     args (opt) options put
     args
@@ -17382,9 +20391,97 @@
     end
 
 } bind def
+/hibcqrcode dup load /uk.co.terryburton.bwipp defineresource pop
+end
+/setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
+% --END ENCODER hibcqrcode--
+
+% --BEGIN ENCODER hibccodablockf--
+% --REQUIRES preamble raiseerror renmatrix codablockf--
+% --DESC: HIBC Codablock F
+% --EXAM: A123BJC5D6E71
+% --EXOP:
+% --RNDR: renmatrix
+%%BeginResource: uk.co.terryburton.bwipp hibccodablockf 0.0 2014121100 61522 64700
+%%BeginData:         74 ASCII Lines
+/setpacking where {pop currentpacking true setpacking} if
+1 dict
+dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
+dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
+dup /codablockf dup /uk.co.terryburton.bwipp findresource put
+begin
+/hibccodablockf {
+
+    20 dict begin                 % Confine variables to local scope
+
+    /options exch def       % We are given an option string
+    /barcode exch def       % We are given a barcode string
+
+    /dontdraw false def
+    /validatecheck false def
+
+    % Parse the input options
+    options type /stringtype eq {
+        1 dict begin
+        options {
+            token false eq {exit} if dup length string cvs (=) search
+            true eq {cvlit exch pop exch def} {cvlit true def} ifelse
+        } loop
+        currentdict end /options exch def
+    } if
+    options {def} forall
+
+    % Create a string of the available characters
+    /barchars (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%) def
+    /charvals 43 dict def
+    0 1 42 {charvals exch dup barchars exch 1 getinterval exch put} for
+
+    % Validate the input
+    0 1 barcode length 1 sub {
+        barcode exch 1 getinterval charvals exch known not {
+            /bwipp.codablockfBadCharacter (HIBC Codablock F must contain only digits, capital letters, spaces and the symbols -.$/+%) //raiseerror exec
+        } if
+    } for
+
+    /barlen barcode length validatecheck {1 sub} if def
+
+    /checksum 41 def
+    0 1 barlen 1 sub {
+        barcode exch 1 getinterval charvals exch get
+        checksum add /checksum exch def
+    } for
+    /checksum checksum 43 mod def
+    validatecheck {
+        barcode barlen get barchars checksum get ne {
+            /bwipp.hibccodablockfBadCheckDigit (Incorrect HIBC Codablock F check digit provided) //raiseerror exec
+        } if
+        /barcode barcode 0 barlen getinterval def
+    } if
+
+    /barcode barlen 2 add string dup 1 barcode putinterval def
+    barcode 0 43 put
+    barcode barlen 1 add barchars checksum get put
+
+    % Get the result of encoding with codablockf
+    options (dontdraw) true put
+    options (validatecheck) false put
+    /args barcode options //codablockf exec def
+
+    args (opt) options put
+    args
+ 
+    dontdraw not //renmatrix if
+
+    end
+
+} bind def
 /hibccodablockf dup load /uk.co.terryburton.bwipp defineresource pop
 end
 /setpacking where {pop setpacking} if
+%%EndData
+%%EndResource
 % --END ENCODER hibccodablockf--
 
 % --END TEMPLATE--

Modified: branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcodegenerator.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19687&path=/branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcodegenerator.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcodegenerator.cpp (original)
+++ branches/Version14x/Scribus/scribus/plugins/barcodegenerator/barcodegenerator.cpp Sat Dec 27 01:57:27 2014
@@ -40,7 +40,7 @@
 	setModal(true);
 	map["EAN-13"] = BarcodeType("ean13", "9781860742712", tr("12 or 13 digits"),
 								"[0-9]{12,13}");
-	map["EAN-8"] = BarcodeType("ean8", "12345678", tr("8 digits"),
+	map["EAN-8"] = BarcodeType("ean8", "12345670", tr("8 digits"),
 							   "[0-9]{8,8}");
 	map["UPC-A"] = BarcodeType("upca", "78858101497", tr("11 or 12 digits"),
 							   "[0-9]{11,12}");
@@ -66,7 +66,7 @@
 	map["UCC/EAN-128"] = BarcodeType("code128", "^104^102Count^0991234^101!",
 									 tr("Variable number of ASCII characters and special function symbols, starting with the appropriate start character for the initial character set. UCC/EAN-128s must have a mandatory FNC 1 symbol immediately following the start character."),
 									 "\\^[0-9a-zA-Z\\^\\!]*");
-	map["Rationalized Codabar"] = BarcodeType("rationalizedCodabar", "0123456789",
+	map["Rationalized Codabar"] = BarcodeType("rationalizedCodabar", "A0123456789D",
 											  tr("Variable number of digits and any of the symbols -$:/.+ABCD."),
 											  "[0-9A-D\\-\\$\\:\\/\\.\\+]*",
 											 true, true);
@@ -81,7 +81,7 @@
 	map["Code 2 of 5"] = BarcodeType("code2of5", "0123456789",
 									 tr("Variable number of digits"),
 									 "[0-9]*");
-	map["Postnet"] = BarcodeType("postnet", "01234567",
+	map["Postnet"] = BarcodeType("postnet", "012345678",
 								 tr("Variable number of digits"),
 								 "[0-9]*",
 								false, true);




More information about the scribus-commit mailing list