@@ -74,13 +74,14 @@ export class GridMatrixCore {
7474
7575 generate ( ) {
7676 const { bytes, eci } = normalizeInput ( this . data , this . options . eci )
77+ const controls = normalizeControls ( this . options )
7778 const requestedMode = this . options . mode == null ? 'auto' : String ( this . options . mode ) . toLowerCase ( )
7879 if ( ! [ 'auto' , 'byte' ] . includes ( requestedMode ) ) {
7980 throw new RangeError ( "Grid Matrix mode must be 'auto' or 'byte'." )
8081 }
8182 const { bits, modes } = requestedMode === 'byte'
82- ? { bits : encodeByteSegments ( bytes , eci ) , modes : Array ( bytes . length ) . fill ( BYTE ) }
83- : encodeOptimized ( bytes , eci )
83+ ? { bits : encodeByteSegments ( bytes , eci , controls . prefix ) , modes : Array ( bytes . length ) . fill ( BYTE ) }
84+ : encodeOptimized ( bytes , eci , controls . prefix )
8485 const dataCodewords = bitsToCodewords ( bits )
8586 const layers = chooseLayers ( dataCodewords . length , this . options . layers )
8687 const eccLevel = chooseEccLevel ( dataCodewords . length , layers , this . options . eccLevel )
@@ -93,6 +94,8 @@ export class GridMatrixCore {
9394 layers,
9495 eccLevel,
9596 eci,
97+ readerInitialization : controls . readerInitialization ,
98+ structuredAppend : controls . structuredAppend ,
9699 encoding : requestedMode ,
97100 modes : modes . map ( mode => MODE_NAMES [ mode - 1 ] ) ,
98101 width : modules . length ,
@@ -105,6 +108,44 @@ export class GridMatrixCore {
105108 }
106109}
107110
111+ function normalizeControls ( options ) {
112+ const requestedReaderInitialization = options . readerInitialization === true
113+ if ( options . readerInitialization != null && typeof options . readerInitialization !== 'boolean' ) {
114+ throw new TypeError ( 'Grid Matrix readerInitialization must be boolean.' )
115+ }
116+
117+ let structuredAppend = null
118+ if ( options . structuredAppend != null ) {
119+ const value = options . structuredAppend
120+ if ( ! value || typeof value !== 'object' || Array . isArray ( value ) ) {
121+ throw new TypeError ( 'Grid Matrix structuredAppend must be an object.' )
122+ }
123+ const count = Number ( value . count ) , index = Number ( value . index )
124+ const id = value . id == null ? 0 : Number ( value . id )
125+ if ( ! Number . isInteger ( count ) || count < 2 || count > 16 ) {
126+ throw new RangeError ( 'Grid Matrix structuredAppend count must be an integer from 2 to 16.' )
127+ }
128+ if ( ! Number . isInteger ( index ) || index < 1 || index > count ) {
129+ throw new RangeError ( 'Grid Matrix structuredAppend index must be an integer from 1 to count.' )
130+ }
131+ if ( ! Number . isInteger ( id ) || id < 0 || id > 255 ) {
132+ throw new RangeError ( 'Grid Matrix structuredAppend id must be an integer from 0 to 255.' )
133+ }
134+ structuredAppend = { index, count, id }
135+ }
136+
137+ const readerInitialization = requestedReaderInitialization && ( ! structuredAppend || structuredAppend . index === 1 )
138+ const prefix = [ ]
139+ if ( readerInitialization ) appendBits ( prefix , 10 , 4 )
140+ if ( structuredAppend ) {
141+ appendBits ( prefix , 9 , 4 )
142+ appendBits ( prefix , structuredAppend . id , 8 )
143+ appendBits ( prefix , structuredAppend . count - 1 , 4 )
144+ appendBits ( prefix , structuredAppend . index - 1 , 4 )
145+ }
146+ return { prefix, readerInitialization, structuredAppend }
147+ }
148+
108149function normalizeInput ( value , requestedEci ) {
109150 let bytes , automaticEci = 0
110151 if ( typeof value === 'string' ) {
@@ -177,8 +218,8 @@ function buildGb2312EncodeMap() {
177218 return map
178219}
179220
180- function encodeByteSegments ( bytes , eci ) {
181- const bits = [ ]
221+ function encodeByteSegments ( bytes , eci , prefix = [ ] ) {
222+ const bits = [ ... prefix ]
182223 appendEci ( bits , eci )
183224 const flatBytes = Array . from ( bytes ) . flatMap ( value => value > 0xFF ? [ value >> 8 , value & 0xFF ] : [ value ] )
184225 for ( let offset = 0 ; offset < flatBytes . length ; offset += 512 ) {
@@ -193,8 +234,8 @@ function encodeByteSegments(bytes, eci) {
193234 return bits
194235}
195236
196- function encodeOptimized ( data , eci ) {
197- const bits = [ ]
237+ function encodeOptimized ( data , eci , prefix = [ ] ) {
238+ const bits = [ ... prefix ]
198239 appendEci ( bits , eci )
199240 const modes = defineModes ( data )
200241 let position = 0 , currentMode = 0 , lastMode = 0
0 commit comments