| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973 |
- //Copyright (c) 2019 by Jason Southwell
- //
- //Permission is hereby granted, free of charge, to any person obtaining a copy
- //of this software and associated documentation files (the "Software"), to deal
- //in the Software without restriction, including without limitation the rights
- //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- //copies of the Software, and to permit persons to whom the Software is
- //furnished to do so, subject to the following conditions:
- //
- //The above copyright notice and this permission notice shall be included in all
- //copies or substantial portions of the Software.
- //
- //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- //SOFTWARE.
- unit qr.code;
- interface
- uses System.SysUtils, System.Classes, System.Generics.Collections, System.Types;
- {$SCOPEDENUMS ON}
- type
- TQRMode = (Numeric, AlphaNumeric, Byte, Kanji);
- TErrorCorrectionLevel = (Auto, Low, Medium, Quartile, High);
- TVersion = ( Auto,
- v1, v2, v3, v4, v5, v6, v7, v8, v9,
- v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
- v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
- v40);
- TMask = (m0, m1, m2, m3, m4, m5, m6, m7, Auto);
- TPaintHandler = reference to procedure(Width, Height : integer; BlackRects : TArray<TRect>);
- TOnStatusHandler = reference to procedure(const Msg : String);
- EQREncodeException = Exception;
- TQRCode = class(TPersistent)
- strict private
- type
- TBlock = TArray<Byte>;
- TGroup = TArray<TBlock>;
- TFinderPosition = (TopLeft, TopRight, BottomLeft);
- TCodeWordField = (DataCodewordCount, ECCodewordsPerBlock, BlocksInGroup1Count, DataCodewordsInGroup1BlockCount, BlocksInGroup2Count, DataCodewordsInGroup2BlockCount);
- TCodeWordFields = Array[TCodeWordField] of integer;
- TCodeWordRequirements = record
- Low : TCodeWordFields;
- Medium : TCodeWordFields;
- Quartile : TCodeWordFields;
- High : TCodeWordFields;
- end;
- TCapacities = record
- Low : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
- Medium : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
- Quartile : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
- High : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
- end;
- TRectHelper = record helper for TRect
- function IntersectsWithRect(const R : TRect) : boolean;
- function IntersectsWithPoint(const pt : TPoint) : boolean;
- end;
- TArrayHelper<T> = class
- strict private
- class procedure NextCombo(Prefix, Source: TArray<T>; Count: Cardinal;
- Result: TArray<TArray<T>>; var ResultIdx: Cardinal); static;
- public
- class function AdvanceArray(Source: TArray<T>; idx: integer): TArray<T>;
- class function Combination(SourceArray : TArray<T>; SubsetSize : Cardinal) : TArray<TArray<T>>;
- end;
- strict private
- class var FVerCapacities : Array[TVersion.v1..TVersion.v40] of TCapacities;
- class var FCodeWordRequirements : Array[TVersion.v1..TVersion.v40] of TCodeWordRequirements;
- strict private
- FOnStatus: TOnStatusHandler;
- FPenaltyScores: TArray<TArray<Integer>>;
- FMaskInUse: TMask;
- FVersion: TVersion;
- FVersionInUse : TVersion;
- FMode: TQRMode;
- FECL: TErrorCorrectionLevel;
- FECLInUse : TErrorCorrectionLevel;
- FData: TArray<Byte>;
- FUpdateDepth : integer;
- FCodeWords : TArray<Byte>;
- FReservedAreas : TList<TRect>;
- FBitsLen : integer;
- FBitsPos : integer;
- FBits : TArray<Boolean>;
- FLogTable : TArray<Byte>;
- FAntilogTable : TArray<Byte>;
- FModules : TArray<TArray<Boolean>>;
- FPixelsPerModule: Integer;
- FDataBits : string;
- FMask : TMask;
- FRenderSize: integer;
- FOnPaint: TPaintHandler;
- procedure SetOnPaint(const Value: TPaintHandler);
- procedure SetPixelsPerModule(const Value: integer);
- procedure SetRenderSize(const Value: integer);
- function GetText: string;
- procedure SetData(const Value: TArray<Byte>);
- procedure SetECL(const Value: TErrorCorrectionLevel);
- procedure SetText(const Value: string);
- procedure SetVersion(const Value: TVersion);
- procedure SetMask(const Value: TMask);
- function Pow(i, k: Integer): Integer;
- function BinaryToDecimal(Str: string): Integer;
- function DecimalToBinary(value, digits: integer): string;
- function DataCodewordCount : integer;
- function GetSize : integer;
- function FinderLocation(pos : TFinderPosition) : TPoint;
- procedure CheckBitsPos;
- function DetermineQRMode : TQRMode;
- procedure WriteMode;
- procedure WriteLength;
- function MinVersion : TVersion;
- function MaxECL : TErrorCorrectionLevel;
- procedure WriteBits(const s : string);
- procedure WriteBit(b : boolean);
- procedure CalculateModules;
- procedure EncodeNumeric;
- procedure EncodeAlphaNumeric;
- procedure EncodeByte;
- procedure EncodeKanji;
- function ReadCodeword(var Pos : integer) : Byte;
- function CodewordCount : integer;
- function OutputAsString : string;
- procedure DrawModules;
- procedure PaintQRCode;
- procedure AddReservedArea(rect : TRect);
- protected
- procedure UpdateCode; virtual;
- procedure SetStatus(const Msg : string); virtual;
- public
- destructor Destroy; override;
- constructor Create; virtual;
- class constructor Create;
- property OnPaint : TPaintHandler read FOnPaint write SetOnPaint;
- property OnStatus : TOnStatusHandler read FOnStatus write FOnStatus;
- property Mode : TQRMode read FMode;
- property VersionInUse : TVersion read FVersionInUse;
- property Data : TArray<Byte> read FData write SetData;
- property ECLInUse : TErrorCorrectionLEvel read FECLInUse;
- property DataBits : string read FDataBits;
- property MaskInUse : TMask read FMaskInUse;
- property Size : integer read GetSize;
- property PenaltyScores : TArray<TArray<Integer>> Read FPenaltyScores;
- procedure BeginUpdate;
- procedure EndUpdate;
- procedure Redraw;
- property Codewords : TArray<Byte> read FCodeWords;
- published
- property Version : TVersion read FVersion write SetVersion;
- property Text : string read GetText write SetText;
- property ECL : TErrorCorrectionLevel read FECL write SetECL;
- property Mask : TMask read FMask write SetMask;
- property RenderSize : integer read FRenderSize write SetRenderSize;
- property PixelsPerModule : integer read FPixelsPerModule write SetPixelsPerModule;
- end;
- implementation
- uses System.Math, qr.rs;
- const
- RemainderBits : Array[TVersion.v1..TVersion.v40] of Byte = (
- 0,
- 7,
- 7,
- 7,
- 7,
- 7,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 3,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- );
- AlphaEncoding : Array[0..44] of char = (
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- ' ',
- '$',
- '%',
- '*',
- '+',
- '-',
- '.',
- '/',
- ':'
- );
- { TQRCode }
- procedure TQRCode.AddReservedArea(rect: TRect);
- begin
- FReservedAreas.Add(rect);
- end;
- procedure TQRCode.BeginUpdate;
- begin
- inc(FUpdateDepth);
- end;
- function TQRCode.BinaryToDecimal(Str: string): Integer;
- var
- Len, i: Integer;
- begin
- Len := Length(Str);
- Result := 0;
- for i:=1 to Len do
- if (Str[i]='0') or (Str[i]='1') then
- Result := Result + Pow(2, Len-i) * StrToInt(Str[i])
- else
- raise EQREncodeException.Create('"'+str+'" is not a binary number');
- end;
- procedure TQRCode.CheckBitsPos;
- begin
- if FBitsLen-FBitsPos < 1024 then
- begin
- inc(FBitsLen, 4096);
- SetLength(FBits, FBitsLen);
- end;
- end;
- function TQRCode.CodewordCount: integer;
- begin
- Result := FBitsPos div 8;
- end;
- class constructor TQRCode.Create;
- procedure AssignCodeWords(Elim : integer; Level : TErrorCorrectionLevel; DCC, ECCPerBlock, BG1, DG1C, BG2, DG2C : integer); overload;
- begin
- case Level of
- TErrorCorrectionLevel.Low:
- begin
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordCount] := DCC;
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.BlocksInGroup1Count] := BG1;
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.BlocksInGroup2Count] := BG2;
- FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
- end;
- TErrorCorrectionLevel.Medium:
- begin
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordCount] := DCC;
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.BlocksInGroup1Count] := BG1;
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.BlocksInGroup2Count] := BG2;
- FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
- end;
- TErrorCorrectionLevel.Quartile:
- begin
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordCount] := DCC;
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.BlocksInGroup1Count] := BG1;
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.BlocksInGroup2Count] := BG2;
- FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
- end;
- TErrorCorrectionLevel.High:
- begin
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordCount] := DCC;
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.BlocksInGroup1Count] := BG1;
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.BlocksInGroup2Count] := BG2;
- FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
- end;
- end;
- end;
- procedure AssignCodeWords(Elim : integer; Level : TErrorCorrectionLevel; DCC, ECCPerBlock, BG1, DG1C : integer); overload;
- begin
- AssignCodeWords(Elim, Level, DCC, ECCPerBlock, BG1, DG1C, 0, 0);
- end;
- procedure AssignVerCapacity(Elim : integer; Level : TErrorCorrectionLevel; Num, Alph, Byt, Kanj : integer);
- begin
- case Level of
- TErrorCorrectionLevel.Low:
- begin
- FVerCapacities[TVersion(Elim)].Low[TQRMode.Numeric] := Num;
- FVerCapacities[TVersion(Elim)].Low[TQRMode.AlphaNumeric] := Alph;
- FVerCapacities[TVersion(Elim)].Low[TQRMode.Byte] := Byt;
- FVerCapacities[TVersion(Elim)].Low[TQRMode.Kanji] := Kanj;
- end;
- TErrorCorrectionLevel.Medium:
- begin
- FVerCapacities[TVersion(Elim)].Medium[TQRMode.Numeric] := Num;
- FVerCapacities[TVersion(Elim)].Medium[TQRMode.AlphaNumeric] := Alph;
- FVerCapacities[TVersion(Elim)].Medium[TQRMode.Byte] := Byt;
- FVerCapacities[TVersion(Elim)].Medium[TQRMode.Kanji] := Kanj;
- end;
- TErrorCorrectionLevel.Quartile:
- begin
- FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Numeric] := Num;
- FVerCapacities[TVersion(Elim)].Quartile[TQRMode.AlphaNumeric] := Alph;
- FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Byte] := Byt;
- FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Kanji] := Kanj;
- end;
- TErrorCorrectionLevel.High:
- begin
- FVerCapacities[TVersion(Elim)].High[TQRMode.Numeric] := Num;
- FVerCapacities[TVersion(Elim)].High[TQRMode.AlphaNumeric] := Alph;
- FVerCapacities[TVersion(Elim)].High[TQRMode.Byte] := Byt;
- FVerCapacities[TVersion(Elim)].High[TQRMode.Kanji] := Kanj;
- end;
- end;
- end;
- begin
- AssignVerCapacity(1 ,TErrorCorrectionLevel.Low ,41 ,25 ,17 ,10);
- AssignVerCapacity(1 ,TErrorCorrectionLevel.Medium, 34 , 20 , 14 , 8);
- AssignVerCapacity(1 ,TErrorCorrectionLevel.Quartile, 27 , 16 , 11 , 7);
- AssignVerCapacity(1 ,TErrorCorrectionLevel.High, 17 , 10 , 7, 4);
- AssignVerCapacity(2 ,TErrorCorrectionLevel.Low ,77 ,47 ,32 ,20);
- AssignVerCapacity(2 ,TErrorCorrectionLevel.Medium, 63 , 38 , 26 , 16);
- AssignVerCapacity(2 ,TErrorCorrectionLevel.Quartile, 48 , 29 , 20 , 12);
- AssignVerCapacity(2 ,TErrorCorrectionLevel.High, 34 , 20 , 14 , 8);
- AssignVerCapacity(3 ,TErrorCorrectionLevel.Low ,127 ,77 ,53 ,32);
- AssignVerCapacity(3 ,TErrorCorrectionLevel.Medium, 101, 61 , 42 , 26);
- AssignVerCapacity(3 ,TErrorCorrectionLevel.Quartile, 77 , 47 , 32 , 20);
- AssignVerCapacity(3 ,TErrorCorrectionLevel.High, 58 , 35 , 24 , 15);
- AssignVerCapacity(4 ,TErrorCorrectionLevel.Low ,187 ,114 ,78 ,48);
- AssignVerCapacity(4 ,TErrorCorrectionLevel.Medium, 149, 90 , 62 , 38);
- AssignVerCapacity(4 ,TErrorCorrectionLevel.Quartile, 111, 67 , 46 , 28);
- AssignVerCapacity(4 ,TErrorCorrectionLevel.High, 82 , 50 , 34 , 21);
- AssignVerCapacity(5 ,TErrorCorrectionLevel.Low ,255 ,154 ,106 ,65);
- AssignVerCapacity(5 ,TErrorCorrectionLevel.Medium, 202, 122, 84 , 52);
- AssignVerCapacity(5 ,TErrorCorrectionLevel.Quartile, 144, 87 , 60 , 37);
- AssignVerCapacity(5 ,TErrorCorrectionLevel.High, 106, 64 , 44 , 27);
- AssignVerCapacity(6 ,TErrorCorrectionLevel.Low ,322 ,195 ,134 ,82);
- AssignVerCapacity(6 ,TErrorCorrectionLevel.Medium, 255, 154, 106, 65);
- AssignVerCapacity(6 ,TErrorCorrectionLevel.Quartile, 178, 108, 74 , 45);
- AssignVerCapacity(6 ,TErrorCorrectionLevel.High, 139, 84 , 58 , 36);
- AssignVerCapacity(7 ,TErrorCorrectionLevel.Low ,370 ,224 ,154 ,95);
- AssignVerCapacity(7 ,TErrorCorrectionLevel.Medium, 293, 178, 122, 75);
- AssignVerCapacity(7 ,TErrorCorrectionLevel.Quartile, 207, 125, 86 , 53);
- AssignVerCapacity(7 ,TErrorCorrectionLevel.High, 154, 93 , 64 , 39);
- AssignVerCapacity(8 ,TErrorCorrectionLevel.Low ,461 ,279 ,192 ,118);
- AssignVerCapacity(8 ,TErrorCorrectionLevel.Medium, 365, 221, 152, 93);
- AssignVerCapacity(8 ,TErrorCorrectionLevel.Quartile, 259, 157, 108, 66);
- AssignVerCapacity(8 ,TErrorCorrectionLevel.High, 202, 122, 84 , 52);
- AssignVerCapacity(9 ,TErrorCorrectionLevel.Low ,552 ,335 ,230 ,141);
- AssignVerCapacity(9 ,TErrorCorrectionLevel.Medium, 432, 262, 180, 111);
- AssignVerCapacity(9 ,TErrorCorrectionLevel.Quartile, 312, 189, 130, 80);
- AssignVerCapacity(9 ,TErrorCorrectionLevel.High, 235, 143, 98 , 60);
- AssignVerCapacity(10 ,TErrorCorrectionLevel.Low ,652 ,395 ,271 ,167);
- AssignVerCapacity(10 ,TErrorCorrectionLevel.Medium, 513, 311, 213, 131);
- AssignVerCapacity(10 ,TErrorCorrectionLevel.Quartile, 364, 221, 151, 93);
- AssignVerCapacity(10 ,TErrorCorrectionLevel.High, 288, 174, 119, 74);
- AssignVerCapacity(11 ,TErrorCorrectionLevel.Low ,772 ,468 ,321 ,198);
- AssignVerCapacity(11 ,TErrorCorrectionLevel.Medium, 604, 366, 251, 155);
- AssignVerCapacity(11 ,TErrorCorrectionLevel.Quartile, 427, 259, 177, 109);
- AssignVerCapacity(11 ,TErrorCorrectionLevel.High, 331, 200, 137, 85);
- AssignVerCapacity(12 ,TErrorCorrectionLevel.Low ,883 ,535 ,367 ,226);
- AssignVerCapacity(12 ,TErrorCorrectionLevel.Medium, 691, 419, 287, 177);
- AssignVerCapacity(12 ,TErrorCorrectionLevel.Quartile, 489, 296, 203, 125);
- AssignVerCapacity(12 ,TErrorCorrectionLevel.High, 374, 227, 155, 96);
- AssignVerCapacity(13 ,TErrorCorrectionLevel.Low ,1022 ,619 ,425 ,262);
- AssignVerCapacity(13 ,TErrorCorrectionLevel.Medium, 796, 483, 331, 204);
- AssignVerCapacity(13 ,TErrorCorrectionLevel.Quartile, 580, 352, 241, 149);
- AssignVerCapacity(13 ,TErrorCorrectionLevel.High, 427, 259, 177, 109);
- AssignVerCapacity(14 ,TErrorCorrectionLevel.Low ,1101 ,667 ,458 ,282);
- AssignVerCapacity(14 ,TErrorCorrectionLevel.Medium, 871, 528, 362, 223);
- AssignVerCapacity(14 ,TErrorCorrectionLevel.Quartile, 621, 376, 258, 159);
- AssignVerCapacity(14 ,TErrorCorrectionLevel.High, 468, 283, 194, 120);
- AssignVerCapacity(15 ,TErrorCorrectionLevel.Low ,1250 ,758 ,520 ,320);
- AssignVerCapacity(15 ,TErrorCorrectionLevel.Medium, 991, 600, 412, 254);
- AssignVerCapacity(15 ,TErrorCorrectionLevel.Quartile, 703, 426, 292, 180);
- AssignVerCapacity(15 ,TErrorCorrectionLevel.High, 530, 321, 220, 136);
- AssignVerCapacity(16 ,TErrorCorrectionLevel.Low ,1408 ,854 ,586 ,361);
- AssignVerCapacity(16 ,TErrorCorrectionLevel.Medium, 1082 , 656, 450, 277);
- AssignVerCapacity(16 ,TErrorCorrectionLevel.Quartile, 775, 470, 322, 198);
- AssignVerCapacity(16 ,TErrorCorrectionLevel.High, 602, 365, 250, 154);
- AssignVerCapacity(17 ,TErrorCorrectionLevel.Low ,1548 ,938 ,644 ,397);
- AssignVerCapacity(17 ,TErrorCorrectionLevel.Medium, 1212 , 734, 504, 310);
- AssignVerCapacity(17 ,TErrorCorrectionLevel.Quartile, 876, 531, 364, 224);
- AssignVerCapacity(17 ,TErrorCorrectionLevel.High, 674, 408, 280, 173);
- AssignVerCapacity(18 ,TErrorCorrectionLevel.Low ,1725 ,1046 ,718 ,442);
- AssignVerCapacity(18 ,TErrorCorrectionLevel.Medium, 1346 , 816, 560, 345);
- AssignVerCapacity(18 ,TErrorCorrectionLevel.Quartile, 948, 574, 394, 243);
- AssignVerCapacity(18 ,TErrorCorrectionLevel.High, 746, 452, 310, 191);
- AssignVerCapacity(19 ,TErrorCorrectionLevel.Low ,1903 ,1153 ,792 ,488);
- AssignVerCapacity(19 ,TErrorCorrectionLevel.Medium, 1500 , 909, 624, 384);
- AssignVerCapacity(19 ,TErrorCorrectionLevel.Quartile, 1063 , 644, 442, 272);
- AssignVerCapacity(19 ,TErrorCorrectionLevel.High, 813, 493, 338, 208);
- AssignVerCapacity(20 ,TErrorCorrectionLevel.Low ,2061 ,1249 ,858 ,528);
- AssignVerCapacity(20 ,TErrorCorrectionLevel.Medium, 1600 , 970, 666, 410);
- AssignVerCapacity(20 ,TErrorCorrectionLevel.Quartile, 1159 , 702, 482, 297);
- AssignVerCapacity(20 ,TErrorCorrectionLevel.High, 919, 557, 382, 235);
- AssignVerCapacity(21 ,TErrorCorrectionLevel.Low ,2232 ,1352 ,929 ,572);
- AssignVerCapacity(21 ,TErrorCorrectionLevel.Medium, 1708 , 1035 , 711, 438);
- AssignVerCapacity(21 ,TErrorCorrectionLevel.Quartile, 1224 , 742, 509, 314);
- AssignVerCapacity(21 ,TErrorCorrectionLevel.High, 969, 587, 403, 248);
- AssignVerCapacity(22 ,TErrorCorrectionLevel.Low ,2409 ,1460 ,1003 ,618);
- AssignVerCapacity(22 ,TErrorCorrectionLevel.Medium, 1872 , 1134 , 779, 480);
- AssignVerCapacity(22 ,TErrorCorrectionLevel.Quartile, 1358 , 823, 565, 348);
- AssignVerCapacity(22 ,TErrorCorrectionLevel.High, 1056 , 640, 439, 270);
- AssignVerCapacity(23 ,TErrorCorrectionLevel.Low ,2620 ,1588 ,1091 ,672);
- AssignVerCapacity(23 ,TErrorCorrectionLevel.Medium, 2059 , 1248 , 857, 528);
- AssignVerCapacity(23 ,TErrorCorrectionLevel.Quartile, 1468 , 890, 611, 376);
- AssignVerCapacity(23 ,TErrorCorrectionLevel.High, 1108 , 672, 461, 284);
- AssignVerCapacity(24 ,TErrorCorrectionLevel.Low ,2812 ,1704 ,1171 ,721);
- AssignVerCapacity(24 ,TErrorCorrectionLevel.Medium, 2188 , 1326 , 911, 561);
- AssignVerCapacity(24 ,TErrorCorrectionLevel.Quartile, 1588 , 963, 661, 407);
- AssignVerCapacity(24 ,TErrorCorrectionLevel.High, 1228 , 744, 511, 315);
- AssignVerCapacity(25 ,TErrorCorrectionLevel.Low ,3057 ,1853 ,1273 ,784);
- AssignVerCapacity(25 ,TErrorCorrectionLevel.Medium, 2395 , 1451 , 997, 614);
- AssignVerCapacity(25 ,TErrorCorrectionLevel.Quartile, 1718 , 1041 , 715, 440);
- AssignVerCapacity(25 ,TErrorCorrectionLevel.High, 1286 , 779, 535, 330);
- AssignVerCapacity(26 ,TErrorCorrectionLevel.Low ,3283 ,1990 ,1367 ,842);
- AssignVerCapacity(26 ,TErrorCorrectionLevel.Medium, 2544 , 1542 , 1059 , 652);
- AssignVerCapacity(26 ,TErrorCorrectionLevel.Quartile, 1804 , 1094 , 751, 462);
- AssignVerCapacity(26 ,TErrorCorrectionLevel.High, 1425 , 864, 593, 365);
- AssignVerCapacity(27 ,TErrorCorrectionLevel.Low ,3517 ,2132 ,1465 ,902);
- AssignVerCapacity(27 ,TErrorCorrectionLevel.Medium, 2701 , 1637 , 1125 , 692);
- AssignVerCapacity(27 ,TErrorCorrectionLevel.Quartile, 1933 , 1172 , 805, 496);
- AssignVerCapacity(27 ,TErrorCorrectionLevel.High, 1501 , 910, 625, 385);
- AssignVerCapacity(28 ,TErrorCorrectionLevel.Low ,3669 ,2223 ,1528 ,940);
- AssignVerCapacity(28 ,TErrorCorrectionLevel.Medium, 2857 , 1732 , 1190 , 732);
- AssignVerCapacity(28 ,TErrorCorrectionLevel.Quartile, 2085 , 1263 , 868, 534);
- AssignVerCapacity(28 ,TErrorCorrectionLevel.High, 1581 , 958, 658, 405);
- AssignVerCapacity(29 ,TErrorCorrectionLevel.Low ,3909 ,2369 ,1628 ,1002);
- AssignVerCapacity(29 ,TErrorCorrectionLevel.Medium, 3035 , 1839 , 1264 , 778);
- AssignVerCapacity(29 ,TErrorCorrectionLevel.Quartile, 2181 , 1322 , 908, 559);
- AssignVerCapacity(29 ,TErrorCorrectionLevel.High, 1677 , 1016 , 698, 430);
- AssignVerCapacity(30 ,TErrorCorrectionLevel.Low ,4158 ,2520 ,1732 ,1066);
- AssignVerCapacity(30 ,TErrorCorrectionLevel.Medium, 3289 , 1994 , 1370 , 843);
- AssignVerCapacity(30 ,TErrorCorrectionLevel.Quartile, 2358 , 1429 , 982, 604);
- AssignVerCapacity(30 ,TErrorCorrectionLevel.High, 1782 , 1080 , 742, 457);
- AssignVerCapacity(31 ,TErrorCorrectionLevel.Low ,4417 ,2677 ,1840 ,1132);
- AssignVerCapacity(31 ,TErrorCorrectionLevel.Medium, 3486 , 2113 , 1452 , 894);
- AssignVerCapacity(31 ,TErrorCorrectionLevel.Quartile, 2473 , 1499 , 1030 , 634);
- AssignVerCapacity(31 ,TErrorCorrectionLevel.High, 1897 , 1150 , 790, 486);
- AssignVerCapacity(32 ,TErrorCorrectionLevel.Low ,4686 ,2840 ,1952 ,1201);
- AssignVerCapacity(32 ,TErrorCorrectionLevel.Medium, 3693 , 2238 , 1538 , 947);
- AssignVerCapacity(32 ,TErrorCorrectionLevel.Quartile, 2670 , 1618 , 1112 , 684);
- AssignVerCapacity(32 ,TErrorCorrectionLevel.High, 2022 , 1226 , 842, 518);
- AssignVerCapacity(33 ,TErrorCorrectionLevel.Low ,4965 ,3009 ,2068 ,1273);
- AssignVerCapacity(33 ,TErrorCorrectionLevel.Medium, 3909 , 2369 , 1628 , 1002);
- AssignVerCapacity(33 ,TErrorCorrectionLevel.Quartile, 2805 , 1700 , 1168 , 719);
- AssignVerCapacity(33 ,TErrorCorrectionLevel.High, 2157 , 1307 , 898, 553);
- AssignVerCapacity(34 ,TErrorCorrectionLevel.Low ,5253 ,3183 ,2188 ,1347);
- AssignVerCapacity(34 ,TErrorCorrectionLevel.Medium, 4134 , 2506 , 1722 , 1060);
- AssignVerCapacity(34 ,TErrorCorrectionLevel.Quartile, 2949 , 1787 , 1228 , 756);
- AssignVerCapacity(34 ,TErrorCorrectionLevel.High, 2301 , 1394 , 958, 590);
- AssignVerCapacity(35 ,TErrorCorrectionLevel.Low ,5529 ,3351 ,2303 ,1417);
- AssignVerCapacity(35 ,TErrorCorrectionLevel.Medium, 4343 , 2632 , 1809 , 1113);
- AssignVerCapacity(35 ,TErrorCorrectionLevel.Quartile, 3081 , 1867 , 1283 , 790);
- AssignVerCapacity(35 ,TErrorCorrectionLevel.High, 2361 , 1431 , 983, 605);
- AssignVerCapacity(36 ,TErrorCorrectionLevel.Low ,5836 ,3537 ,2431 ,1496);
- AssignVerCapacity(36 ,TErrorCorrectionLevel.Medium, 4588 , 2780 , 1911 , 1176);
- AssignVerCapacity(36 ,TErrorCorrectionLevel.Quartile, 3244 , 1966 , 1351 , 832);
- AssignVerCapacity(36 ,TErrorCorrectionLevel.High, 2524 , 1530 , 1051 , 647);
- AssignVerCapacity(37 ,TErrorCorrectionLevel.Low ,6153 ,3729 ,2563 ,1577);
- AssignVerCapacity(37 ,TErrorCorrectionLevel.Medium, 4775 , 2894 , 1989 , 1224);
- AssignVerCapacity(37 ,TErrorCorrectionLevel.Quartile, 3417 , 2071 , 1423 , 876);
- AssignVerCapacity(37 ,TErrorCorrectionLevel.High, 2625 , 1591 , 1093 , 673);
- AssignVerCapacity(38 ,TErrorCorrectionLevel.Low ,6479 ,3927 ,2699 ,1661);
- AssignVerCapacity(38 ,TErrorCorrectionLevel.Medium, 5039 , 3054 , 2099 , 1292);
- AssignVerCapacity(38 ,TErrorCorrectionLevel.Quartile, 3599 , 2181 , 1499 , 923);
- AssignVerCapacity(38 ,TErrorCorrectionLevel.High, 2735 , 1658 , 1139 , 701);
- AssignVerCapacity(39 ,TErrorCorrectionLevel.Low ,6743 ,4087 ,2809 ,1729);
- AssignVerCapacity(39 ,TErrorCorrectionLevel.Medium, 5313 , 3220 , 2213 , 1362);
- AssignVerCapacity(39 ,TErrorCorrectionLevel.Quartile, 3791 , 2298 , 1579 , 972);
- AssignVerCapacity(39 ,TErrorCorrectionLevel.High, 2927 , 1774 , 1219 , 750);
- AssignVerCapacity(40 ,TErrorCorrectionLevel.Low ,7089 ,4296 ,2953 ,1817);
- AssignVerCapacity(40 ,TErrorCorrectionLevel.Medium, 5596 , 3391 , 2331 , 1435);
- AssignVerCapacity(40 ,TErrorCorrectionLevel.Quartile, 3993 , 2420 , 1663 , 1024);
- AssignVerCapacity(40 ,TErrorCorrectionLevel.High, 3057 , 1852 , 1273 , 784);
- AssignCodeWords(1, TErrorCorrectionLevel.Low, 19 ,7 ,1 ,19 );
- AssignCodeWords(1, TErrorCorrectionLevel.Medium, 16 ,10 ,1 ,16 );
- AssignCodeWords(1, TErrorCorrectionLevel.Quartile, 13 ,13 ,1 ,13 );
- AssignCodeWords(1, TErrorCorrectionLevel.High, 9 ,17 ,1 ,9 );
- AssignCodeWords(2, TErrorCorrectionLevel.Low, 34 ,10 ,1 ,34 );
- AssignCodeWords(2, TErrorCorrectionLevel.Medium, 28 ,16 ,1 ,28 );
- AssignCodeWords(2, TErrorCorrectionLevel.Quartile, 22 ,22 ,1 ,22 );
- AssignCodeWords(2, TErrorCorrectionLevel.High, 16 ,28 ,1 ,16 );
- AssignCodeWords(3, TErrorCorrectionLevel.Low, 55 ,15 ,1 ,55 );
- AssignCodeWords(3, TErrorCorrectionLevel.Medium, 44 ,26 ,1 ,44 );
- AssignCodeWords(3, TErrorCorrectionLevel.Quartile, 34 ,18 ,2 ,17 );
- AssignCodeWords(3, TErrorCorrectionLevel.High, 26 ,22 ,2 ,13 );
- AssignCodeWords(4, TErrorCorrectionLevel.Low, 80 ,20 ,1 ,80 );
- AssignCodeWords(4, TErrorCorrectionLevel.Medium, 64 ,18 ,2 ,32 );
- AssignCodeWords(4, TErrorCorrectionLevel.Quartile, 48 ,26 ,2 ,24 );
- AssignCodeWords(4, TErrorCorrectionLevel.High, 36 ,16 ,4 ,9 );
- AssignCodeWords(5, TErrorCorrectionLevel.Low, 108 ,26 ,1 ,108 );
- AssignCodeWords(5, TErrorCorrectionLevel.Medium, 86 ,24 ,2 ,43 );
- AssignCodeWords(5, TErrorCorrectionLevel.Quartile, 62 ,18 ,2 ,15 ,2 ,16 );
- AssignCodeWords(5, TErrorCorrectionLevel.High, 46 ,22 ,2 ,11 ,2 ,12 );
- AssignCodeWords(6, TErrorCorrectionLevel.Low, 136 ,18 ,2 ,68 );
- AssignCodeWords(6, TErrorCorrectionLevel.Medium, 108 ,16 ,4 ,27 );
- AssignCodeWords(6, TErrorCorrectionLevel.Quartile, 76 ,24 ,4 ,19 );
- AssignCodeWords(6, TErrorCorrectionLevel.High, 60 ,28 ,4 ,15 );
- AssignCodeWords(7, TErrorCorrectionLevel.Low, 156 ,20 ,2 ,78 );
- AssignCodeWords(7, TErrorCorrectionLevel.Medium, 124 ,18 ,4 ,31 );
- AssignCodeWords(7, TErrorCorrectionLevel.Quartile, 88 ,18 ,2 ,14 ,4 ,15 );
- AssignCodeWords(7, TErrorCorrectionLevel.High, 66 ,26 ,4 ,13 ,1 ,14 );
- AssignCodeWords(8, TErrorCorrectionLevel.Low, 194 ,24 ,2 ,97 );
- AssignCodeWords(8, TErrorCorrectionLevel.Medium, 154 ,22 ,2 ,38 ,2 ,39 );
- AssignCodeWords(8, TErrorCorrectionLevel.Quartile, 110 ,22 ,4 ,18 ,2 ,19 );
- AssignCodeWords(8, TErrorCorrectionLevel.High, 86 ,26 ,4 ,14 ,2 ,15 );
- AssignCodeWords(9, TErrorCorrectionLevel.Low, 232 ,30 ,2 ,116 );
- AssignCodeWords(9, TErrorCorrectionLevel.Medium, 182 ,22 ,3 ,36 ,2 ,37 );
- AssignCodeWords(9, TErrorCorrectionLevel.Quartile, 132 ,20 ,4 ,16 ,4 ,17 );
- AssignCodeWords(9, TErrorCorrectionLevel.High, 100 ,24 ,4 ,12 ,4 ,13 );
- AssignCodeWords(10, TErrorCorrectionLevel.Low, 274 ,18 ,2 ,68 ,2 ,69 );
- AssignCodeWords(10, TErrorCorrectionLevel.Medium, 216 ,26 ,4 ,43 ,1 ,44 );
- AssignCodeWords(10, TErrorCorrectionLevel.Quartile, 154 ,24 ,6 ,19 ,2 ,20 );
- AssignCodeWords(10, TErrorCorrectionLevel.High, 122 ,28 ,6 ,15 ,2 ,16 );
- AssignCodeWords(11, TErrorCorrectionLevel.Low, 324 ,20 ,4 ,81 );
- AssignCodeWords(11, TErrorCorrectionLevel.Medium, 254 ,30 ,1 ,50 ,4 ,51 );
- AssignCodeWords(11, TErrorCorrectionLevel.Quartile, 180 ,28 ,4 ,22 ,4 ,23 );
- AssignCodeWords(11, TErrorCorrectionLevel.High, 140 ,24 ,3 ,12 ,8 ,13 );
- AssignCodeWords(12, TErrorCorrectionLevel.Low, 370 ,24 ,2 ,92 ,2 ,93 );
- AssignCodeWords(12, TErrorCorrectionLevel.Medium, 290 ,22 ,6 ,36 ,2 ,37 );
- AssignCodeWords(12, TErrorCorrectionLevel.Quartile, 206 ,26 ,4 ,20 ,6 ,21 );
- AssignCodeWords(12, TErrorCorrectionLevel.High, 158 ,28 ,7 ,14 ,4 ,15 );
- AssignCodeWords(13, TErrorCorrectionLevel.Low, 428 ,26 ,4 ,107);
- AssignCodeWords(13, TErrorCorrectionLevel.Medium, 334 ,22 ,8 ,37 ,1 ,38 );
- AssignCodeWords(13, TErrorCorrectionLevel.Quartile, 244 ,24 ,8 ,20 ,4 ,21 );
- AssignCodeWords(13, TErrorCorrectionLevel.High, 180 ,22 ,12 ,11 ,4 ,12 );
- AssignCodeWords(14, TErrorCorrectionLevel.Low, 461 ,30 ,3 ,115 ,1 ,116 );
- AssignCodeWords(14, TErrorCorrectionLevel.Medium, 365 ,24 ,4 ,40 ,5 ,41 );
- AssignCodeWords(14, TErrorCorrectionLevel.Quartile, 261 ,20 ,11 ,16 ,5 ,17 );
- AssignCodeWords(14, TErrorCorrectionLevel.High, 197 ,24 ,11 ,12 ,5 ,13 );
- AssignCodeWords(15, TErrorCorrectionLevel.Low, 523 ,22 ,5 ,87 ,1 ,88 );
- AssignCodeWords(15, TErrorCorrectionLevel.Medium, 415 ,24 ,5 ,41 ,5 ,42 );
- AssignCodeWords(15, TErrorCorrectionLevel.Quartile, 295 ,30 ,5 ,24 ,7 ,25 );
- AssignCodeWords(15, TErrorCorrectionLevel.High, 223 ,24 ,11 ,12 ,7 ,13 );
- AssignCodeWords(16, TErrorCorrectionLevel.Low, 589 ,24 ,5 ,98 ,1 ,99 );
- AssignCodeWords(16, TErrorCorrectionLevel.Medium, 453 ,28 ,7 ,45 ,3 ,46 );
- AssignCodeWords(16, TErrorCorrectionLevel.Quartile, 325 ,24 ,15 ,19 ,2 ,20 );
- AssignCodeWords(16, TErrorCorrectionLevel.High, 253 ,30 ,3 ,15 ,13 ,16 );
- AssignCodeWords(17, TErrorCorrectionLevel.Low, 647 ,28 ,1 ,107 ,5 ,108 );
- AssignCodeWords(17, TErrorCorrectionLevel.Medium, 507 ,28 ,10 ,46 ,1 ,47 );
- AssignCodeWords(17, TErrorCorrectionLevel.Quartile, 367 ,28 ,1 ,22 ,15 ,23 );
- AssignCodeWords(17, TErrorCorrectionLevel.High, 283 ,28 ,2 ,14 ,17 ,15 );
- AssignCodeWords(18, TErrorCorrectionLevel.Low, 721 ,30 ,5 ,120 ,1 ,121 );
- AssignCodeWords(18, TErrorCorrectionLevel.Medium, 563 ,26 ,9 ,43 ,4 ,44 );
- AssignCodeWords(18, TErrorCorrectionLevel.Quartile, 397 ,28 ,17 ,22 ,1 ,23 );
- AssignCodeWords(18, TErrorCorrectionLevel.High, 313 ,28 ,2 ,14 ,19 ,15 );
- AssignCodeWords(19, TErrorCorrectionLevel.Low, 795 ,28 ,3 ,113 ,4 ,114 );
- AssignCodeWords(19, TErrorCorrectionLevel.Medium, 627 ,26 ,3 ,44 ,11 ,45 );
- AssignCodeWords(19, TErrorCorrectionLevel.Quartile, 445 ,26 ,17 ,21 ,4 ,22 );
- AssignCodeWords(19, TErrorCorrectionLevel.High, 341 ,26 ,9 ,13 ,16 ,14 );
- AssignCodeWords(20, TErrorCorrectionLevel.Low, 861 ,28 ,3 ,107 ,5 ,108 );
- AssignCodeWords(20, TErrorCorrectionLevel.Medium, 669 ,26 ,3 ,41 ,13 ,42 );
- AssignCodeWords(20, TErrorCorrectionLevel.Quartile, 485 ,30 ,15 ,24 ,5 ,25 );
- AssignCodeWords(20, TErrorCorrectionLevel.High, 385 ,28 ,15 ,15 ,10 ,16 );
- AssignCodeWords(21, TErrorCorrectionLevel.Low, 932 ,28 ,4 ,116 ,4 ,117 );
- AssignCodeWords(21, TErrorCorrectionLevel.Medium, 714 ,26 ,17 ,42 );
- AssignCodeWords(21, TErrorCorrectionLevel.Quartile, 512 ,28 ,17 ,22 ,6 ,23 );
- AssignCodeWords(21, TErrorCorrectionLevel.High, 406 ,30 ,19 ,16 ,6 ,17 );
- AssignCodeWords(22, TErrorCorrectionLevel.Low, 1006 ,28 ,2 ,111 ,7 ,112 );
- AssignCodeWords(22, TErrorCorrectionLevel.Medium, 782 ,28 ,17 ,46 );
- AssignCodeWords(22, TErrorCorrectionLevel.Quartile, 568 ,30 ,7 ,24 ,16 ,25 );
- AssignCodeWords(22, TErrorCorrectionLevel.High, 442 ,24 ,34 ,13 );
- AssignCodeWords(23, TErrorCorrectionLevel.Low, 1094 ,30 ,4 ,121 ,5 ,122 );
- AssignCodeWords(23, TErrorCorrectionLevel.Medium, 860 ,28 ,4 ,47 ,14 ,48 );
- AssignCodeWords(23, TErrorCorrectionLevel.Quartile, 614 ,30 ,11 ,24 ,14 ,25 );
- AssignCodeWords(23, TErrorCorrectionLevel.High, 464 ,30 ,16 ,15 ,14 ,16 );
- AssignCodeWords(24, TErrorCorrectionLevel.Low, 1174 ,30 ,6 ,117 ,4 ,118 );
- AssignCodeWords(24, TErrorCorrectionLevel.Medium, 914 ,28 ,6 ,45 ,14 ,46 );
- AssignCodeWords(24, TErrorCorrectionLevel.Quartile, 664 ,30 ,11 ,24 ,16 ,25 );
- AssignCodeWords(24, TErrorCorrectionLevel.High, 514 ,30 ,30 ,16 ,2 ,17 );
- AssignCodeWords(25, TErrorCorrectionLevel.Low, 1276 ,26 ,8 ,106 ,4 ,107 );
- AssignCodeWords(25, TErrorCorrectionLevel.Medium, 1000 ,28 ,8 ,47 ,13 ,48 );
- AssignCodeWords(25, TErrorCorrectionLevel.Quartile, 718 ,30 ,7 ,24 ,22 ,25 );
- AssignCodeWords(25, TErrorCorrectionLevel.High, 538 ,30 ,22 ,15 ,13 ,16 );
- AssignCodeWords(26, TErrorCorrectionLevel.Low, 1370 ,28 ,10 ,114 ,2 ,115 );
- AssignCodeWords(26, TErrorCorrectionLevel.Medium, 1062 ,28 ,19 ,46 ,4 ,47 );
- AssignCodeWords(26, TErrorCorrectionLevel.Quartile, 754 ,28 ,28 ,22 ,6 ,23 );
- AssignCodeWords(26, TErrorCorrectionLevel.High, 596 ,30 ,33 ,16 ,4 ,17 );
- AssignCodeWords(27, TErrorCorrectionLevel.Low, 1468 ,30 ,8 ,122 ,4 ,123 );
- AssignCodeWords(27, TErrorCorrectionLevel.Medium, 1128 ,28 ,22 ,45 ,3 ,46 );
- AssignCodeWords(27, TErrorCorrectionLevel.Quartile, 808 ,30 ,8 ,23 ,26 ,24 );
- AssignCodeWords(27, TErrorCorrectionLevel.High, 628 ,30 ,12 ,15 ,28 ,16 );
- AssignCodeWords(28, TErrorCorrectionLevel.Low, 1531 ,30 ,3 ,117 ,10 ,118 );
- AssignCodeWords(28, TErrorCorrectionLevel.Medium, 1193 ,28 ,3 ,45 ,23 ,46 );
- AssignCodeWords(28, TErrorCorrectionLevel.Quartile, 871 ,30 ,4 ,24 ,31 ,25 );
- AssignCodeWords(28, TErrorCorrectionLevel.High, 661 ,30 ,11 ,15 ,31 ,16 );
- AssignCodeWords(29, TErrorCorrectionLevel.Low, 1631 ,30 ,7 ,116 ,7 ,117 );
- AssignCodeWords(29, TErrorCorrectionLevel.Medium, 1267 ,28 ,21 ,45 ,7 ,46 );
- AssignCodeWords(29, TErrorCorrectionLevel.Quartile, 911 ,30 ,1 ,23 ,37 ,24 );
- AssignCodeWords(29, TErrorCorrectionLevel.High, 701 ,30 ,19 ,15 ,26 ,16 );
- AssignCodeWords(30, TErrorCorrectionLevel.Low, 1735 ,30 ,5 ,115 ,10 ,116 );
- AssignCodeWords(30, TErrorCorrectionLevel.Medium, 1373 ,28 ,19 ,47 ,10 ,48 );
- AssignCodeWords(30, TErrorCorrectionLevel.Quartile, 985 ,30 ,15 ,24 ,25 ,25 );
- AssignCodeWords(30, TErrorCorrectionLevel.High, 745 ,30 ,23 ,15 ,25 ,16 );
- AssignCodeWords(31, TErrorCorrectionLevel.Low, 1843 ,30 ,13 ,115 ,3 ,116 );
- AssignCodeWords(31, TErrorCorrectionLevel.Medium, 1455 ,28 ,2 ,46 ,29 ,47 );
- AssignCodeWords(31, TErrorCorrectionLevel.Quartile, 1033 ,30 ,42 ,24 ,1 ,25 );
- AssignCodeWords(31, TErrorCorrectionLevel.High, 793 ,30 ,23 ,15 ,28 ,16 );
- AssignCodeWords(32, TErrorCorrectionLevel.Low, 1955, 30, 17 , 115);
- AssignCodeWords(32, TErrorCorrectionLevel.Medium, 1541 ,28 ,10 ,46 ,23 ,47 );
- AssignCodeWords(32, TErrorCorrectionLevel.Quartile, 1115 ,30 ,10 ,24 ,35 ,25 );
- AssignCodeWords(32, TErrorCorrectionLevel.High, 845 ,30 ,19 ,15 ,35 ,16 );
- AssignCodeWords(33, TErrorCorrectionLevel.Low, 2071 ,30 ,17 ,115 ,1 ,116 );
- AssignCodeWords(33, TErrorCorrectionLevel.Medium, 1631 ,28 ,14 ,46 ,21 ,47 );
- AssignCodeWords(33, TErrorCorrectionLevel.Quartile, 1171 ,30 ,29 ,24 ,19 ,25 );
- AssignCodeWords(33, TErrorCorrectionLevel.High, 901 ,30 ,11 ,15 ,46 ,16 );
- AssignCodeWords(34, TErrorCorrectionLevel.Low, 2191 ,30 ,13 ,115 ,6 ,116 );
- AssignCodeWords(34, TErrorCorrectionLevel.Medium, 1725 ,28 ,14 ,46 ,23 ,47 );
- AssignCodeWords(34, TErrorCorrectionLevel.Quartile, 1231 ,30 ,44 ,24 ,7 ,25 );
- AssignCodeWords(34, TErrorCorrectionLevel.High, 961 ,30 ,59 ,16 ,1 ,17 );
- AssignCodeWords(35, TErrorCorrectionLevel.Low, 2306 ,30 ,12 ,121 ,7 ,122 );
- AssignCodeWords(35, TErrorCorrectionLevel.Medium, 1812 ,28 ,12 ,47 ,26 ,48 );
- AssignCodeWords(35, TErrorCorrectionLevel.Quartile, 1286 ,30 ,39 ,24 ,14 ,25 );
- AssignCodeWords(35, TErrorCorrectionLevel.High, 986 ,30 ,22 ,15 ,41 ,16 );
- AssignCodeWords(36, TErrorCorrectionLevel.Low, 2434 ,30 ,6 ,121 ,14 ,122 );
- AssignCodeWords(36, TErrorCorrectionLevel.Medium, 1914 ,28 ,6 ,47 ,34 ,48 );
- AssignCodeWords(36, TErrorCorrectionLevel.Quartile, 1354 ,30 ,46 ,24 ,10 ,25 );
- AssignCodeWords(36, TErrorCorrectionLevel.High, 1054 ,30 ,2 ,15 ,64 ,16 );
- AssignCodeWords(37, TErrorCorrectionLevel.Low, 2566 ,30 ,17 ,122 ,4 ,123 );
- AssignCodeWords(37, TErrorCorrectionLevel.Medium, 1992 ,28 ,29 ,46 ,14 ,47 );
- AssignCodeWords(37, TErrorCorrectionLevel.Quartile, 1426 ,30 ,49 ,24 ,10 ,25 );
- AssignCodeWords(37, TErrorCorrectionLevel.High, 1096 ,30 ,24 ,15 ,46 ,16 );
- AssignCodeWords(38, TErrorCorrectionLevel.Low, 2702 ,30 ,4 ,122 ,18 ,123 );
- AssignCodeWords(38, TErrorCorrectionLevel.Medium, 2102 ,28 ,13 ,46 ,32 ,47 );
- AssignCodeWords(38, TErrorCorrectionLevel.Quartile, 1502 ,30 ,48 ,24 ,14 ,25 );
- AssignCodeWords(38, TErrorCorrectionLevel.High, 1142 ,30 ,42 ,15 ,32 ,16 );
- AssignCodeWords(39, TErrorCorrectionLevel.Low, 2812 ,30 ,20 ,117 ,4 ,118 );
- AssignCodeWords(39, TErrorCorrectionLevel.Medium, 2216 ,28 ,40 ,47 ,7 ,48 );
- AssignCodeWords(39, TErrorCorrectionLevel.Quartile, 1582 ,30 ,43 ,24 ,22 ,25 );
- AssignCodeWords(39, TErrorCorrectionLevel.High, 1222 ,30 ,10 ,15 ,67 ,16 );
- AssignCodeWords(40, TErrorCorrectionLevel.Low, 2956 ,30 ,19 ,118 ,6 ,119 );
- AssignCodeWords(40, TErrorCorrectionLevel.Medium, 2334 ,28 ,18 ,47 ,31 ,48 );
- AssignCodeWords(40, TErrorCorrectionLevel.Quartile, 1666 ,30 ,34 ,24 ,34 ,25 );
- AssignCodeWords(40, TErrorCorrectionLevel.High, 1276 ,30 ,20 ,15 ,61 ,16 );
- end;
- constructor TQRCode.Create;
- var
- i: Integer;
- begin
- inherited Create;
- FUpdateDepth := 0;
- FReservedAreas := TList<TRect>.Create;
- SetLength(FPenaltyScores,8);
- for i := 0 to 7 do
- SetLength(FPenaltyScores[i],4);
- FMaskInUse := TMask.m0;
- FMask := TMask.Auto;
- FVersion := TVersion.Auto;
- FVersionInUse := TVersion.v1;
- FMode := TQRMode.Numeric;
- FECL := TErrorCorrectionLevel.Auto;
- FECLInUse := TErrorCorrectionLevel.Low;
- SetLength(FData,0);
- SetLength(FCodeWords, 0);
- FBitsLen := 0;
- FBitsPos := 0;
- SetLength(FBits,0);
- SetLength(FModules,0);
- FDataBits := '';
- FOnPaint := nil;
- SetLength(FLogTable, 256);
- FLogTable[0] := 1;
- FLogTable[1] := 2;
- FLogTable[2] := 4;
- FLogTable[3] := 8;
- FLogTable[4] := 16;
- FLogTable[5] := 32;
- FLogTable[6] := 64;
- FLogTable[7] := 128;
- FLogTable[8] := 29;
- FLogTable[9] := 58;
- FLogTable[10] := 116;
- FLogTable[11] := 232;
- FLogTable[12] := 205;
- FLogTable[13] := 135;
- FLogTable[14] := 19;
- FLogTable[15] := 38;
- FLogTable[16] := 76;
- FLogTable[17] := 152;
- FLogTable[18] := 45;
- FLogTable[19] := 90;
- FLogTable[20] := 180;
- FLogTable[21] := 117;
- FLogTable[22] := 234;
- FLogTable[23] := 201;
- FLogTable[24] := 143;
- FLogTable[25] := 3;
- FLogTable[26] := 6;
- FLogTable[27] := 12;
- FLogTable[28] := 24;
- FLogTable[29] := 48;
- FLogTable[30] := 96;
- FLogTable[31] := 192;
- FLogTable[32] := 157;
- FLogTable[33] := 39;
- FLogTable[34] := 78;
- FLogTable[35] := 156;
- FLogTable[36] := 37;
- FLogTable[37] := 74;
- FLogTable[38] := 148;
- FLogTable[39] := 53;
- FLogTable[40] := 106;
- FLogTable[41] := 212;
- FLogTable[42] := 181;
- FLogTable[43] := 119;
- FLogTable[44] := 238;
- FLogTable[45] := 193;
- FLogTable[46] := 159;
- FLogTable[47] := 35;
- FLogTable[48] := 70;
- FLogTable[49] := 140;
- FLogTable[50] := 5;
- FLogTable[51] := 10;
- FLogTable[52] := 20;
- FLogTable[53] := 40;
- FLogTable[54] := 80;
- FLogTable[55] := 160;
- FLogTable[56] := 93;
- FLogTable[57] := 186;
- FLogTable[58] := 105;
- FLogTable[59] := 210;
- FLogTable[60] := 185;
- FLogTable[61] := 111;
- FLogTable[62] := 222;
- FLogTable[63] := 161;
- FLogTable[64] := 95;
- FLogTable[65] := 190;
- FLogTable[66] := 97;
- FLogTable[67] := 194;
- FLogTable[68] := 153;
- FLogTable[69] := 47;
- FLogTable[70] := 94;
- FLogTable[71] := 188;
- FLogTable[72] := 101;
- FLogTable[73] := 202;
- FLogTable[74] := 137;
- FLogTable[75] := 15;
- FLogTable[76] := 30;
- FLogTable[77] := 60;
- FLogTable[78] := 120;
- FLogTable[79] := 240;
- FLogTable[80] := 253;
- FLogTable[81] := 231;
- FLogTable[82] := 211;
- FLogTable[83] := 187;
- FLogTable[84] := 107;
- FLogTable[85] := 214;
- FLogTable[86] := 177;
- FLogTable[87] := 127;
- FLogTable[88] := 254;
- FLogTable[89] := 225;
- FLogTable[90] := 223;
- FLogTable[91] := 163;
- FLogTable[92] := 91;
- FLogTable[93] := 182;
- FLogTable[94] := 113;
- FLogTable[95] := 226;
- FLogTable[96] := 217;
- FLogTable[97] := 175;
- FLogTable[98] := 67;
- FLogTable[99] := 134;
- FLogTable[100] := 17;
- FLogTable[101] := 34;
- FLogTable[102] := 68;
- FLogTable[103] := 136;
- FLogTable[104] := 13;
- FLogTable[105] := 26;
- FLogTable[106] := 52;
- FLogTable[107] := 104;
- FLogTable[108] := 208;
- FLogTable[109] := 189;
- FLogTable[110] := 103;
- FLogTable[111] := 206;
- FLogTable[112] := 129;
- FLogTable[113] := 31;
- FLogTable[114] := 62;
- FLogTable[115] := 124;
- FLogTable[116] := 248;
- FLogTable[117] := 237;
- FLogTable[118] := 199;
- FLogTable[119] := 147;
- FLogTable[120] := 59;
- FLogTable[121] := 118;
- FLogTable[122] := 236;
- FLogTable[123] := 197;
- FLogTable[124] := 151;
- FLogTable[125] := 51;
- FLogTable[126] := 102;
- FLogTable[127] := 204;
- FLogTable[128] := 133;
- FLogTable[129] := 23;
- FLogTable[130] := 46;
- FLogTable[131] := 92;
- FLogTable[132] := 184;
- FLogTable[133] := 109;
- FLogTable[134] := 218;
- FLogTable[135] := 169;
- FLogTable[136] := 79;
- FLogTable[137] := 158;
- FLogTable[138] := 33;
- FLogTable[139] := 66;
- FLogTable[140] := 132;
- FLogTable[141] := 21;
- FLogTable[142] := 42;
- FLogTable[143] := 84;
- FLogTable[144] := 168;
- FLogTable[145] := 77;
- FLogTable[146] := 154;
- FLogTable[147] := 41;
- FLogTable[148] := 82;
- FLogTable[149] := 164;
- FLogTable[150] := 85;
- FLogTable[151] := 170;
- FLogTable[152] := 73;
- FLogTable[153] := 146;
- FLogTable[154] := 57;
- FLogTable[155] := 114;
- FLogTable[156] := 228;
- FLogTable[157] := 213;
- FLogTable[158] := 183;
- FLogTable[159] := 115;
- FLogTable[160] := 230;
- FLogTable[161] := 209;
- FLogTable[162] := 191;
- FLogTable[163] := 99;
- FLogTable[164] := 198;
- FLogTable[165] := 145;
- FLogTable[166] := 63;
- FLogTable[167] := 126;
- FLogTable[168] := 252;
- FLogTable[169] := 229;
- FLogTable[170] := 215;
- FLogTable[171] := 179;
- FLogTable[172] := 123;
- FLogTable[173] := 246;
- FLogTable[174] := 241;
- FLogTable[175] := 255;
- FLogTable[176] := 227;
- FLogTable[177] := 219;
- FLogTable[178] := 171;
- FLogTable[179] := 75;
- FLogTable[180] := 150;
- FLogTable[181] := 49;
- FLogTable[182] := 98;
- FLogTable[183] := 196;
- FLogTable[184] := 149;
- FLogTable[185] := 55;
- FLogTable[186] := 110;
- FLogTable[187] := 220;
- FLogTable[188] := 165;
- FLogTable[189] := 87;
- FLogTable[190] := 174;
- FLogTable[191] := 65;
- FLogTable[192] := 130;
- FLogTable[193] := 25;
- FLogTable[194] := 50;
- FLogTable[195] := 100;
- FLogTable[196] := 200;
- FLogTable[197] := 141;
- FLogTable[198] := 7;
- FLogTable[199] := 14;
- FLogTable[200] := 28;
- FLogTable[201] := 56;
- FLogTable[202] := 112;
- FLogTable[203] := 224;
- FLogTable[204] := 221;
- FLogTable[205] := 167;
- FLogTable[206] := 83;
- FLogTable[207] := 166;
- FLogTable[208] := 81;
- FLogTable[209] := 162;
- FLogTable[210] := 89;
- FLogTable[211] := 178;
- FLogTable[212] := 121;
- FLogTable[213] := 242;
- FLogTable[214] := 249;
- FLogTable[215] := 239;
- FLogTable[216] := 195;
- FLogTable[217] := 155;
- FLogTable[218] := 43;
- FLogTable[219] := 86;
- FLogTable[220] := 172;
- FLogTable[221] := 69;
- FLogTable[222] := 138;
- FLogTable[223] := 9;
- FLogTable[224] := 18;
- FLogTable[225] := 36;
- FLogTable[226] := 72;
- FLogTable[227] := 144;
- FLogTable[228] := 61;
- FLogTable[229] := 122;
- FLogTable[230] := 244;
- FLogTable[231] := 245;
- FLogTable[232] := 247;
- FLogTable[233] := 243;
- FLogTable[234] := 251;
- FLogTable[235] := 235;
- FLogTable[236] := 203;
- FLogTable[237] := 139;
- FLogTable[238] := 11;
- FLogTable[239] := 22;
- FLogTable[240] := 44;
- FLogTable[241] := 88;
- FLogTable[242] := 176;
- FLogTable[243] := 125;
- FLogTable[244] := 250;
- FLogTable[245] := 233;
- FLogTable[246] := 207;
- FLogTable[247] := 131;
- FLogTable[248] := 27;
- FLogTable[249] := 54;
- FLogTable[250] := 108;
- FLogTable[251] := 216;
- FLogTable[252] := 173;
- FLogTable[253] := 71;
- FLogTable[254] := 142;
- FLogTable[255] := 1;
- SetLength(FAntilogTable, 256);
- FAntilogTable[1] := 0;
- FAntilogTable[2] := 1;
- FAntilogTable[3] := 25;
- FAntilogTable[4] := 2;
- FAntilogTable[5] := 50;
- FAntilogTable[6] := 26;
- FAntilogTable[7] := 198;
- FAntilogTable[8] := 3;
- FAntilogTable[9] := 223;
- FAntilogTable[10] := 51;
- FAntilogTable[11] := 238;
- FAntilogTable[12] := 27;
- FAntilogTable[13] := 104;
- FAntilogTable[14] := 199;
- FAntilogTable[15] := 75;
- FAntilogTable[16] := 4;
- FAntilogTable[17] := 100;
- FAntilogTable[18] := 224;
- FAntilogTable[19] := 14;
- FAntilogTable[20] := 52;
- FAntilogTable[21] := 141;
- FAntilogTable[22] := 239;
- FAntilogTable[23] := 129;
- FAntilogTable[24] := 28;
- FAntilogTable[25] := 193;
- FAntilogTable[26] := 105;
- FAntilogTable[27] := 248;
- FAntilogTable[28] := 200;
- FAntilogTable[29] := 8;
- FAntilogTable[30] := 76;
- FAntilogTable[31] := 113;
- FAntilogTable[32] := 5;
- FAntilogTable[33] := 138;
- FAntilogTable[34] := 101;
- FAntilogTable[35] := 47;
- FAntilogTable[36] := 225;
- FAntilogTable[37] := 36;
- FAntilogTable[38] := 15;
- FAntilogTable[39] := 33;
- FAntilogTable[40] := 53;
- FAntilogTable[41] := 147;
- FAntilogTable[42] := 142;
- FAntilogTable[43] := 218;
- FAntilogTable[44] := 240;
- FAntilogTable[45] := 18;
- FAntilogTable[46] := 130;
- FAntilogTable[47] := 69;
- FAntilogTable[48] := 29;
- FAntilogTable[49] := 181;
- FAntilogTable[50] := 194;
- FAntilogTable[51] := 125;
- FAntilogTable[52] := 106;
- FAntilogTable[53] := 39;
- FAntilogTable[54] := 249;
- FAntilogTable[55] := 185;
- FAntilogTable[56] := 201;
- FAntilogTable[57] := 154;
- FAntilogTable[58] := 9;
- FAntilogTable[59] := 120;
- FAntilogTable[60] := 77;
- FAntilogTable[61] := 228;
- FAntilogTable[62] := 114;
- FAntilogTable[63] := 166;
- FAntilogTable[64] := 6;
- FAntilogTable[65] := 191;
- FAntilogTable[66] := 139;
- FAntilogTable[67] := 98;
- FAntilogTable[68] := 102;
- FAntilogTable[69] := 221;
- FAntilogTable[70] := 48;
- FAntilogTable[71] := 253;
- FAntilogTable[72] := 226;
- FAntilogTable[73] := 152;
- FAntilogTable[74] := 37;
- FAntilogTable[75] := 179;
- FAntilogTable[76] := 16;
- FAntilogTable[77] := 145;
- FAntilogTable[78] := 34;
- FAntilogTable[79] := 136;
- FAntilogTable[80] := 54;
- FAntilogTable[81] := 208;
- FAntilogTable[82] := 148;
- FAntilogTable[83] := 206;
- FAntilogTable[84] := 143;
- FAntilogTable[85] := 150;
- FAntilogTable[86] := 219;
- FAntilogTable[87] := 189;
- FAntilogTable[88] := 241;
- FAntilogTable[89] := 210;
- FAntilogTable[90] := 19;
- FAntilogTable[91] := 92;
- FAntilogTable[92] := 131;
- FAntilogTable[93] := 56;
- FAntilogTable[94] := 70;
- FAntilogTable[95] := 64;
- FAntilogTable[96] := 30;
- FAntilogTable[97] := 66;
- FAntilogTable[98] := 182;
- FAntilogTable[99] := 163;
- FAntilogTable[100] := 195;
- FAntilogTable[101] := 72;
- FAntilogTable[102] := 126;
- FAntilogTable[103] := 110;
- FAntilogTable[104] := 107;
- FAntilogTable[105] := 58;
- FAntilogTable[106] := 40;
- FAntilogTable[107] := 84;
- FAntilogTable[108] := 250;
- FAntilogTable[109] := 133;
- FAntilogTable[110] := 186;
- FAntilogTable[111] := 61;
- FAntilogTable[112] := 202;
- FAntilogTable[113] := 94;
- FAntilogTable[114] := 155;
- FAntilogTable[115] := 159;
- FAntilogTable[116] := 10;
- FAntilogTable[117] := 21;
- FAntilogTable[118] := 121;
- FAntilogTable[119] := 43;
- FAntilogTable[120] := 78;
- FAntilogTable[121] := 212;
- FAntilogTable[122] := 229;
- FAntilogTable[123] := 172;
- FAntilogTable[124] := 115;
- FAntilogTable[125] := 243;
- FAntilogTable[126] := 167;
- FAntilogTable[127] := 87;
- FAntilogTable[128] := 7;
- FAntilogTable[129] := 112;
- FAntilogTable[130] := 192;
- FAntilogTable[131] := 247;
- FAntilogTable[132] := 140;
- FAntilogTable[133] := 128;
- FAntilogTable[134] := 99;
- FAntilogTable[135] := 13;
- FAntilogTable[136] := 103;
- FAntilogTable[137] := 74;
- FAntilogTable[138] := 222;
- FAntilogTable[139] := 237;
- FAntilogTable[140] := 49;
- FAntilogTable[141] := 197;
- FAntilogTable[142] := 254;
- FAntilogTable[143] := 24;
- FAntilogTable[144] := 227;
- FAntilogTable[145] := 165;
- FAntilogTable[146] := 153;
- FAntilogTable[147] := 119;
- FAntilogTable[148] := 38;
- FAntilogTable[149] := 184;
- FAntilogTable[150] := 180;
- FAntilogTable[151] := 124;
- FAntilogTable[152] := 17;
- FAntilogTable[153] := 68;
- FAntilogTable[154] := 146;
- FAntilogTable[155] := 217;
- FAntilogTable[156] := 35;
- FAntilogTable[157] := 32;
- FAntilogTable[158] := 137;
- FAntilogTable[159] := 46;
- FAntilogTable[160] := 55;
- FAntilogTable[161] := 63;
- FAntilogTable[162] := 209;
- FAntilogTable[163] := 91;
- FAntilogTable[164] := 149;
- FAntilogTable[165] := 188;
- FAntilogTable[166] := 207;
- FAntilogTable[167] := 205;
- FAntilogTable[168] := 144;
- FAntilogTable[169] := 135;
- FAntilogTable[170] := 151;
- FAntilogTable[171] := 178;
- FAntilogTable[172] := 220;
- FAntilogTable[173] := 252;
- FAntilogTable[174] := 190;
- FAntilogTable[175] := 97;
- FAntilogTable[176] := 242;
- FAntilogTable[177] := 86;
- FAntilogTable[178] := 211;
- FAntilogTable[179] := 171;
- FAntilogTable[180] := 20;
- FAntilogTable[181] := 42;
- FAntilogTable[182] := 93;
- FAntilogTable[183] := 158;
- FAntilogTable[184] := 132;
- FAntilogTable[185] := 60;
- FAntilogTable[186] := 57;
- FAntilogTable[187] := 83;
- FAntilogTable[188] := 71;
- FAntilogTable[189] := 109;
- FAntilogTable[190] := 65;
- FAntilogTable[191] := 162;
- FAntilogTable[192] := 31;
- FAntilogTable[193] := 45;
- FAntilogTable[194] := 67;
- FAntilogTable[195] := 216;
- FAntilogTable[196] := 183;
- FAntilogTable[197] := 123;
- FAntilogTable[198] := 164;
- FAntilogTable[199] := 118;
- FAntilogTable[200] := 196;
- FAntilogTable[201] := 23;
- FAntilogTable[202] := 73;
- FAntilogTable[203] := 236;
- FAntilogTable[204] := 127;
- FAntilogTable[205] := 12;
- FAntilogTable[206] := 111;
- FAntilogTable[207] := 246;
- FAntilogTable[208] := 108;
- FAntilogTable[209] := 161;
- FAntilogTable[210] := 59;
- FAntilogTable[211] := 82;
- FAntilogTable[212] := 41;
- FAntilogTable[213] := 157;
- FAntilogTable[214] := 85;
- FAntilogTable[215] := 170;
- FAntilogTable[216] := 251;
- FAntilogTable[217] := 96;
- FAntilogTable[218] := 134;
- FAntilogTable[219] := 177;
- FAntilogTable[220] := 187;
- FAntilogTable[221] := 204;
- FAntilogTable[222] := 62;
- FAntilogTable[223] := 90;
- FAntilogTable[224] := 203;
- FAntilogTable[225] := 89;
- FAntilogTable[226] := 95;
- FAntilogTable[227] := 176;
- FAntilogTable[228] := 156;
- FAntilogTable[229] := 169;
- FAntilogTable[230] := 160;
- FAntilogTable[231] := 81;
- FAntilogTable[232] := 11;
- FAntilogTable[233] := 245;
- FAntilogTable[234] := 22;
- FAntilogTable[235] := 235;
- FAntilogTable[236] := 122;
- FAntilogTable[237] := 117;
- FAntilogTable[238] := 44;
- FAntilogTable[239] := 215;
- FAntilogTable[240] := 79;
- FAntilogTable[241] := 174;
- FAntilogTable[242] := 213;
- FAntilogTable[243] := 233;
- FAntilogTable[244] := 230;
- FAntilogTable[245] := 231;
- FAntilogTable[246] := 173;
- FAntilogTable[247] := 232;
- FAntilogTable[248] := 116;
- FAntilogTable[249] := 214;
- FAntilogTable[250] := 244;
- FAntilogTable[251] := 234;
- FAntilogTable[252] := 168;
- FAntilogTable[253] := 80;
- FAntilogTable[254] := 88;
- FAntilogTable[255] := 175;
- PixelsPerModule := 15;
- end;
- function TQRCode.DecimalToBinary(value, digits: integer): string;
- var
- i: integer;
- begin
- if digits > 32 then
- digits := 32;
- Result := '';
- i := 0;
- while i < digits do
- begin
- if ((1 shl i) and value) > 0 then
- Result := '1' + Result
- else
- Result := '0' + Result;
- inc(i);
- end;
- end;
- destructor TQRCode.Destroy;
- begin
- FReservedAreas.Free;
- inherited;
- end;
- function TQRCode.DetermineQRMode : TQRMode;
- var
- i: Integer;
- begin
- Result := TQRMode.Numeric;
- if length(FData) = 0 then
- exit;
- for i := 0 to Length(FData)-1 do
- if (not CharInSet(Char(FData[i]), ['0'..'9'])) then
- begin
- if (not CharInSet(Char(FData[i]),['0'..'9', 'A'..'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'])) then
- begin
- (*if {(Ord(s.Chars[i]) > 256) or }(TEncoding.UTF8.GetString(FData) <> TEncoding.Unicode.GetString(FData)) then
- begin
- Result := TQRMode.Kanji;
- end else if (Result < TQRMode.Byte) then*)
- Result := TQRMode.Byte;
- end else if (Result < TQRMode.AlphaNumeric) then
- Result := TQRMode.AlphaNumeric;
- end;
- end;
- procedure TQRCode.DrawModules;
- procedure DrawFinder(fp : TFinderPosition);
- var
- pt : TPoint;
- x, y: Integer;
- begin
- pt := FinderLocation(fp);
- for x := 0 to 6 do
- for y := 0 to 6 do
- begin
- FModules[x + pt.x][y + pt.y] :=
- (x = 0) or
- (x = 6) or
- (y = 0) or
- (y = 6) or
- ((x >= 2) and (x <= 4) and (y >= 2) and (y <= 4)) // center
- end;
- case fp of
- TFinderPosition.TopLeft: ;
- TFinderPosition.TopRight:
- pt.Offset(-1,0);
- TFinderPosition.BottomLeft:
- pt.Offset(0,-1);
- end;
- AddReservedArea(TRect.Create(pt,8,8));
- end;
- procedure DrawAlignmentPatterns;
- procedure DrawAlignmentPatternAt(pt : TPoint);
- var
- i: Integer;
- fp : TFinderPosition;
- ptfp : TPoint;
- rectAP : TRect;
- rectFinder : TRect;
- x: Integer;
- y: Integer;
- begin
- pt.Offset(-2,-2);
- rectAP := TRect.Create(pt,5,5);
- for i := 0 to 2 do
- begin
- fp := TFinderPosition(i);
- ptfp := FinderLocation(fp);
- case fp of
- TFinderPosition.TopRight:
- ptfp.SetLocation(ptfp.X, ptfp.Y);
- TFinderPosition.BottomLeft:
- ptfp.SetLocation(ptfp.X, ptfp.Y);
- end;
- rectFinder := TRect.Create(ptfp,8,8);
- if rectAP.IntersectsWithRect(rectFinder) then
- exit;
- end;
- for x := 0 to 4 do
- for y := 0 to 4 do
- FModules[x + pt.x][y + pt.Y] :=
- (x = 0) or
- (x = 4) or
- (y = 0) or
- (y = 4) or
- ((x = 2) and (y = 2));
- AddReservedArea(TRect.Create(pt, 4,4));
- end;
- var
- Locs : TArray<Integer>;
- Points : TArray<TArray<Integer>>;
- i: Integer;
- idx : integer;
- begin
- case FVersionInUse of
- TVersion.v1: SetLength(Locs,0);
- TVersion.v2:
- begin
- SetLength(Locs,2);
- Locs[0] := 6;
- Locs[1] := 18;
- end;
- TVersion.v3:
- begin
- SetLength(Locs,2);
- Locs[0] := 6;
- Locs[1] := 22;
- end;
- TVersion.v4:
- begin
- SetLength(Locs,2);
- Locs[0] := 6;
- Locs[1] := 26;
- end;
- TVersion.v5:
- begin
- SetLength(Locs,2);
- Locs[0] := 6;
- Locs[1] := 30;
- end;
- TVersion.v6:
- begin
- SetLength(Locs,2);
- Locs[0] := 6;
- Locs[1] := 34;
- end;
- TVersion.v7:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 22;
- Locs[2] := 38;
- end;
- TVersion.v8:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 24;
- Locs[2] := 42;
- end;
- TVersion.v9:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 46;
- end;
- TVersion.v10:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 28;
- Locs[2] := 50;
- end;
- TVersion.v11:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 54;
- end;
- TVersion.v12:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 32;
- Locs[2] := 58;
- end;
- TVersion.v13:
- begin
- SetLength(Locs,3);
- Locs[0] := 6;
- Locs[1] := 34;
- Locs[2] := 62;
- end;
- TVersion.v14:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 46;
- Locs[3] := 66;
- end;
- TVersion.v15:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 48;
- Locs[3] := 70;
- end;
- TVersion.v16:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 50;
- Locs[3] := 74;
- end;
- TVersion.v17:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 54;
- Locs[3] := 78;
- end;
- TVersion.v18:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 56;
- Locs[3] := 82;
- end;
- TVersion.v19:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 58;
- Locs[3] := 86;
- end;
- TVersion.v20:
- begin
- SetLength(Locs,4);
- Locs[0] := 6;
- Locs[1] := 34;
- Locs[2] := 62;
- Locs[3] := 90;
- end;
- TVersion.v21:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 28;
- Locs[2] := 50;
- Locs[3] := 72;
- Locs[4] := 94;
- end;
- TVersion.v22:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 50;
- Locs[3] := 74;
- Locs[4] := 98;
- end;
- TVersion.v23:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 54;
- Locs[3] := 78;
- Locs[4] := 102;
- end;
- TVersion.v24:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 28;
- Locs[2] := 54;
- Locs[3] := 80;
- Locs[4] := 106;
- end;
- TVersion.v25:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 32;
- Locs[2] := 58;
- Locs[3] := 84;
- Locs[4] := 110;
- end;
- TVersion.v26:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 58;
- Locs[3] := 86;
- Locs[4] := 114;
- end;
- TVersion.v27:
- begin
- SetLength(Locs,5);
- Locs[0] := 6;
- Locs[1] := 34;
- Locs[2] := 62;
- Locs[3] := 90;
- Locs[4] := 118;
- end;
- TVersion.v28:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 50;
- Locs[3] := 74;
- Locs[4] := 98;
- Locs[5] := 122;
- end;
- TVersion.v29:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 54;
- Locs[3] := 78;
- Locs[4] := 102;
- Locs[5] := 126;
- end;
- TVersion.v30:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 52;
- Locs[3] := 78;
- Locs[4] := 104;
- Locs[5] := 130;
- end;
- TVersion.v31:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 56;
- Locs[3] := 82;
- Locs[4] := 108;
- Locs[5] := 134;
- end;
- TVersion.v32:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 34;
- Locs[2] := 60;
- Locs[3] := 86;
- Locs[4] := 112;
- Locs[5] := 138;
- end;
- TVersion.v33:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 58;
- Locs[3] := 86;
- Locs[4] := 114;
- Locs[5] := 142;
- end;
- TVersion.v34:
- begin
- SetLength(Locs,6);
- Locs[0] := 6;
- Locs[1] := 34;
- Locs[2] := 62;
- Locs[3] := 90;
- Locs[4] := 118;
- Locs[5] := 146;
- end;
- TVersion.v35:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 54;
- Locs[3] := 78;
- Locs[4] := 102;
- Locs[5] := 126;
- Locs[6] := 150;
- end;
- TVersion.v36:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 24;
- Locs[2] := 50;
- Locs[3] := 76;
- Locs[4] := 102;
- Locs[5] := 128;
- Locs[6] := 154;
- end;
- TVersion.v37:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 28;
- Locs[2] := 54;
- Locs[3] := 80;
- Locs[4] := 106;
- Locs[5] := 132;
- Locs[6] := 158;
- end;
- TVersion.v38:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 32;
- Locs[2] := 58;
- Locs[3] := 84;
- Locs[4] := 110;
- Locs[5] := 136;
- Locs[6] := 162;
- end;
- TVersion.v39:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 26;
- Locs[2] := 54;
- Locs[3] := 82;
- Locs[4] := 110;
- Locs[5] := 138;
- Locs[6] := 166;
- end;
- TVersion.v40:
- begin
- SetLength(Locs,7);
- Locs[0] := 6;
- Locs[1] := 30;
- Locs[2] := 58;
- Locs[3] := 86;
- Locs[4] := 114;
- Locs[5] := 142;
- Locs[6] := 170;
- end;
- end;
- if Length(Locs) > 0 then
- begin
- Points := TArrayHelper<Integer>.Combination(Locs, 2);
- SetLength(Points, Length(Points)+Length(Locs));
- for i := Length(Locs)-1 downto 0 do
- begin
- setLength(Points[Length(Points)-i-1],2);
- Points[Length(Points)-i-1][0] := Locs[i];
- Points[Length(Points)-i-1][1] := Locs[i];
- end;
- for i := Length(Points)-1 downto 0 do
- begin
- if Points[i][0] <> Points[i][1] then
- begin
- SetLength(Points, length(Points)+1);
- idx := length(Points)-1;
- SetLength(Points[idx],2);
- Points[idx][0] := Points[i][1];
- Points[idx][1] := Points[i][0];
- end;
- end;
- for i := 0 to length(Points)-1 do
- begin
- DrawAlignmentPatternAt(TPoint.Create(Points[i][0], Points[i][1]));
- end;
- end;
- end;
- procedure DrawTimingPatterns;
- var
- x, y: Integer;
- begin
- y := 6;
- for x := 8 to Size-9 do
- begin
- FModules[x][y] := (x+1) mod 2 <> 0;
- FModules[y][x] := (x+1) mod 2 <> 0;
- end;
- end;
- procedure DrawDarkModule;
- var
- pt : TPoint;
- begin
- pt := FinderLocation(TFinderPosition.BottomLeft);
- pt.Offset(8,-1);
- FModules[pt.X][pt.Y] := True;
- AddReservedArea(TRect.Create(pt,0,0));
- end;
- procedure ReserveFormatArea;
- begin
- AddReservedArea(TRect.Create(0,8, 8, 8));
- AddReservedArea(TRect.Create(8,0, 8, 8));
- AddReservedArea(TRect.Create(8,FinderLocation(TFinderPosition.BottomLeft).Y,8,FinderLocation(TFinderPosition.BottomLeft).Y+8));
- AddReservedArea(TRect.Create(FinderLocation(TFinderPosition.TopRight).X-1,8, FinderLocation(TFinderPosition.TopRight).X+7,8));
- end;
- procedure ReserveVersionArea;
- begin
- if FVersionInUse >= TVersion.v7 then
- begin
- AddReservedArea(TRect.Create(FinderLocation(TFinderPosition.TopRight).X-4,0,FinderLocation(TFinderPosition.TopRight).X-2,5));
- AddReservedArea(TRect.Create(0, FinderLocation(TFinderPosition.BottomLeft).Y-4,5,FinderLocation(TFinderPosition.BottomLeft).Y-2));
- end;
- end;
- function IsPointReserved(pt : TPoint) : Boolean;
- var
- i: Integer;
- begin
- Result := (pt.x = 6) or (pt.y = 6);
- if not Result then
- for i := 0 to FReservedAreas.Count-1 do
- if FReservedAreas[i].IntersectsWithPoint(pt) then
- begin
- Result := True;
- exit;
- end;
- end;
- procedure DrawDataBits;
- var
- x, y, idx : integer;
- begin
- x := Size-1;
- idx := 0;
- repeat
- y := Size-1;
- repeat
- if y = 6 then
- begin
- dec(y);
- continue;
- end;
- if idx < DataBits.Length then
- begin
- if not IsPointReserved(TPoint.Create(x,y)) then
- begin
- FModules[x,y] := DataBits.Chars[idx] = '1';
- inc(idx);
- end;
- end;
- if idx < DataBits.Length then
- begin
- if not IsPointReserved(TPoint.Create(x-1,y)) then
- begin
- FModules[x-1,y] := DataBits.Chars[idx] = '1';
- inc(idx);
- end;
- end;
- dec(y);
- until y<0;
- dec(x,2);
- if x = 6 then
- dec(x);
- y := 0;
- repeat
- if y = 6 then
- begin
- inc(y);
- continue;
- end;
- if idx < DataBits.Length then
- begin
- if not IsPointReserved(TPoint.Create(x,y)) then
- begin
- FModules[x,y] := DataBits.Chars[idx] = '1';
- inc(idx);
- end;
- end;
- if idx < DataBits.Length then
- begin
- if not IsPointReserved(TPoint.Create(x-1,y)) then
- begin
- FModules[x-1,y] := DataBits.Chars[idx] = '1';
- inc(idx);
- end;
- end;
- inc(y);
- until y >= Size;
- dec(x,2);
- if x = 6 then
- dec(x);
- until (x<0);
- end;
- procedure DrawMaskPattern;
- procedure ApplyMask(Pattern : TMask; var ary : TArray<TArray<Boolean>>);
- var
- x: Integer;
- y: Integer;
- pt : TPoint;
- begin
- if Pattern = TMask.Auto then
- raise EQREncodeException.Create('Cannot apply invalid mask.');
- for y := 0 to Size-1 do
- for x := 0 to Size-1 do
- begin
- pt := TPoint.Create(x, y);;
- if not IsPointReserved(pt) then
- begin
- case Integer(Pattern) of
- 0: if (y + x) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- 1: if (y) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- 2: if (x) mod 3 = 0 then
- ary[x][y] := not ary[x][y];
- 3: if (y + x) mod 3 = 0 then
- ary[x][y] := not ary[x][y];
- 4: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- 5: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- 6: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- 7: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
- ary[x][y] := not ary[x][y];
- end;
- end;
- end;
- FMaskInUse := Pattern;
- end;
- function PenaltyScore(Mask : integer; ary : TArray<TArray<Boolean>>) : integer;
- function PenaltyTest1 : integer;
- var
- y, x: Integer;
- iColorCnt : integer;
- bLastColor : boolean;
- begin
- Result := 0;
- for y := 0 to Size-1 do
- begin
- iColorCnt := 1;
- bLastColor := ary[0][y];
- for x := 1 to Size-1 do
- begin
- if ary[x][y] = bLastColor then
- begin
- inc(iColorCnt);
- if iColorCnt = 5 then
- inc(Result,3)
- else if iColorCnt > 5 then
- inc(Result,1);
- end else
- begin
- iColorCnt := 1;
- bLastColor := not bLastColor;
- end;
- end;
- end;
- for x := 0 to Size-1 do
- begin
- iColorCnt := 1;
- bLastColor := ary[x][0];
- for y := 1 to Size-1 do
- begin
- if ary[x][y] = bLastColor then
- begin
- inc(iColorCnt);
- if iColorCnt = 5 then
- inc(Result,3)
- else if iColorCnt > 5 then
- inc(Result,1);
- end else
- begin
- iColorCnt := 1;
- bLastColor := not bLastColor;
- end;
- end;
- end;
- end;
- function PenaltyTest2 : integer;
- var
- y, x: Integer;
- begin
- Result := 0;
- for x := 0 to Size-2 do
- for y := 0 to Size-2 do
- begin
- if (ary[x][y] = ary[x+1][y]) and
- (ary[x][y] = ary[x][y+1]) and
- (ary[x][y] = ary[x+1][y+1]) then
- inc(Result,3);
- end;
- end;
- function PenaltyTest3 : integer;
- var
- y, x: Integer;
- begin
- Result := 0;
- for y := 0 to Size-1 do
- for x := 0 to Size-12 do
- begin
- if (ary[x][y] and (not ary[x+1][y]) and ary[x+2][y] and ary[x+3][y] and ary[x+4][y] and (not ary[x+5][y]) and ary[x+6][y] and (not ary[x+7][y]) and (not ary[x+8][y]) and (not ary[x+9][y]) and (not ary[x+10][y])) or
- ((not ary[x][y]) and (not ary[x+1][y]) and (not ary[x+2][y]) and (not ary[x+3][y]) and ary[x+4][y] and (not ary[x+5][y]) and ary[x+6][y] and ary[x+7][y] and ary[x+8][y] and (not ary[x+9][y]) and ary[x+10][y]) then
- inc(Result,40);
- end;
- for x := 0 to Size-1 do
- for y := 0 to Size-12 do
- begin
- if (ary[x][y] and (not ary[x][y+1]) and ary[x][y+2] and ary[x][y+3] and ary[x][y+4] and (not ary[x][y+5]) and ary[x][y+6] and (not ary[x][y+7]) and (not ary[x][y+8]) and (not ary[x][y+9]) and (not ary[x][y+10])) or
- ((not ary[x][y]) and (not ary[x][y+1]) and (not ary[x][y+2]) and (not ary[x][y+3]) and ary[x][y+4] and (not ary[x][y+5]) and ary[x][y+6] and ary[x][y+7] and ary[x][y+8] and (not ary[x][y+9]) and ary[x][y+10]) then
- inc(Result,40);
- end;
- end;
- function PenaltyTest4 : integer;
- var
- x: Integer;
- y: Integer;
- iCnt, iColor : integer;
- iPercent, iLow, iHigh : integer;
- begin
- iCnt := 0;
- iColor := 0;
- for x := 0 to Size-1 do
- for y := 0 to Size-1 do
- begin
- inc(iCnt);
- if ary[x][y] then
- inc(iColor);
- end;
- if iCnt = 0 then
- begin
- result := 0;
- exit;
- end;
- iPercent := Trunc((iColor / iCnt) * 100);
- iLow := iPercent -1;
- iHigh := iPercent +1;
- while iLow mod 5 <> 0 do
- dec(iLow);
- while iHigh mod 5 <> 0 do
- inc(iHigh);
- Result := Min(Abs(iLow-50), Abs(iHigh-50))*10;
- end;
- begin
- FPenaltyScores[Mask][0] := PenaltyTest1;
- FPenaltyScores[Mask][1] := PenaltyTest2;
- FPenaltyScores[Mask][2] := PenaltyTest3;
- FPenaltyScores[Mask][3] := PenaltyTest4;
- Result :=
- FPenaltyScores[Mask][0] +
- FPenaltyScores[Mask][1] +
- FPenaltyScores[Mask][2] +
- FPenaltyScores[Mask][3] ;
- end;
- var
- ary : TArray<TArray<Boolean>>;
- iScore, iLowScore, iSelected : integer;
- i, x, y: Integer;
- begin
- iSelected := 0;
- iLowScore := High(Integer);
- for i := 0 to 7 do
- begin
- SetLength(ary, Length(FModules));
- for y := 0 to Length(FModules)-1 do
- begin
- SetLength(ary[y], Length(FModules[y]));
- end;
- for y := 0 to Length(FModules)-1 do
- begin
- for x := 0 to length(FModules[y])-1 do
- ary[x][y] := FModules[x][y];
- end;
- ApplyMask(TMask(i), ary);
- iScore := PenaltyScore(i, ary);
- if iScore < iLowScore then
- begin
- iLowScore := iScore;
- iSelected := i;
- end;
- end;
- if FMask = TMask.Auto then
- ApplyMask(TMask(iSelected), FModules)
- else
- ApplyMask(FMask, FModules);
- end;
- procedure DrawFormat;
- function FormatString : string;
- begin
- case FECLInUse of
- TErrorCorrectionLevel.Low:
- case Integer(FMaskInUse) of
- 0: Result := '111011111000100';
- 1: Result := '111001011110011';
- 2: Result := '111110110101010';
- 3: Result := '111100010011101';
- 4: Result := '110011000101111';
- 5: Result := '110001100011000';
- 6: Result := '110110001000001';
- 7: Result := '110100101110110';
- end;
- TErrorCorrectionLevel.Medium:
- case Integer(FMaskInUse) of
- 0: Result := '101010000010010';
- 1: Result := '101000100100101';
- 2: Result := '101111001111100';
- 3: Result := '101101101001011';
- 4: Result := '100010111111001';
- 5: Result := '100000011001110';
- 6: Result := '100111110010111';
- 7: Result := '100101010100000';
- end;
- TErrorCorrectionLevel.Quartile:
- case Integer(FMaskInUse) of
- 0: Result := '011010101011111';
- 1: Result := '011000001101000';
- 2: Result := '011111100110001';
- 3: Result := '011101000000110';
- 4: Result := '010010010110100';
- 5: Result := '010000110000011';
- 6: Result := '010111011011010';
- 7: Result := '010101111101101';
- end;
- TErrorCorrectionLevel.High:
- case Integer(FMaskInUse) of
- 0: Result := '001011010001001';
- 1: Result := '001001110111110';
- 2: Result := '001110011100111';
- 3: Result := '001100111010000';
- 4: Result := '000011101100010';
- 5: Result := '000001001010101';
- 6: Result := '000110100001100';
- 7: Result := '000100000111011';
- end;
- end;
- end;
- var
- s : string;
- sFmt : string;
- x, y : integer;
- y2 : integer;
- x2 : integer;
- begin
- sFmt := FormatString;
- x := 0;
- y := 8;
- y2 := Size-1;
- x2 := 8;
- for s in sFmt do
- begin
- FModules[x][y] := s = '1';
- if x < 8 then
- inc(x)
- else
- dec(y);
- if x = 6 then
- inc(x);
- if y = 6 then
- dec(y);
- FModules[x2][y2] := s = '1';
- if y2 <= Size-7 then
- begin
- if y2 = Size-7 then
- begin
- y2 := 8;
- x2 := Size-8;
- end else
- inc(x2);
- end else
- dec(y2)
- end;
- end;
- procedure DrawVersion;
- var
- sVer : string;
- s: string;
- x, y, x2, y2 : integer;
- i: Integer;
- begin
- if FVersionInUse >= TVersion.v7 then
- begin
- case FVersionInUse of
- TVersion.v7 : sVer := '000111110010010100';
- TVersion.v8 : sVer := '001000010110111100';
- TVersion.v9 : sVer := '001001101010011001';
- TVersion.v10 : sVer := '001010010011010011';
- TVersion.v11 : sVer := '001011101111110110';
- TVersion.v12 : sVer := '001100011101100010';
- TVersion.v13 : sVer := '001101100001000111';
- TVersion.v14 : sVer := '001110011000001101';
- TVersion.v15 : sVer := '001111100100101000';
- TVersion.v16 : sVer := '010000101101111000';
- TVersion.v17 : sVer := '010001010001011101';
- TVersion.v18 : sVer := '010010101000010111';
- TVersion.v19 : sVer := '010011010100110010';
- TVersion.v20 : sVer := '010100100110100110';
- TVersion.v21 : sVer := '010101011010000011';
- TVersion.v22 : sVer := '010110100011001001';
- TVersion.v23 : sVer := '010111011111101100';
- TVersion.v24 : sVer := '011000111011000100';
- TVersion.v25 : sVer := '011001000111100001';
- TVersion.v26 : sVer := '011010111110101011';
- TVersion.v27 : sVer := '011011000010001110';
- TVersion.v28 : sVer := '011100110000011010';
- TVersion.v29 : sVer := '011101001100111111';
- TVersion.v30 : sVer := '011110110101110101';
- TVersion.v31 : sVer := '011111001001010000';
- TVersion.v32 : sVer := '100000100111010101';
- TVersion.v33 : sVer := '100001011011110000';
- TVersion.v34 : sVer := '100010100010111010';
- TVersion.v35 : sVer := '100011011110011111';
- TVersion.v36 : sVer := '100100101100001011';
- TVersion.v37 : sVer := '100101010000101110';
- TVersion.v38 : sVer := '100110101001100100';
- TVersion.v39 : sVer := '100111010101000001';
- TVersion.v40 : sVer := '101000110001101001';
- end;
- s := sVer;
- for i := 1 to Length(sVer) do
- begin
- s[length(sVer)-i+1] := sVer[i];
- end;
- sVer := s;
- x := 0;
- y := FinderLocation(TFinderPosition.BottomLeft).Y-4;
- x2 := FinderLocation(TFinderPosition.TopRight).X-4;
- y2 := 0;
- for s in sVer do
- begin
- FModules[x][y] := s = '1';
- inc(y);
- if y >= FinderLocation(TFinderPosition.BottomLeft).Y-1 then
- begin
- inc(x);
- y := FinderLocation(TFinderPosition.BottomLeft).Y-4;
- end;
- FModules[x2][y2] := s = '1';
- inc(x2);
- if x2 >= FinderLocation(TFinderPosition.TopRight).X-1 then
- begin
- inc(y2);
- x2 := FinderLocation(TFinderPosition.TopRight).X-4;
- end;
- end;
- end;
- end;
- var
- i: Integer;
- fp: TFinderPosition;
- j: Integer;
- begin
- SetLength(FModules, Size);
- for i := 0 to Length(FModules) - 1 do
- begin
- SetLength(FModules[i], Size);
- for j := 0 to Length(FModules[i])-1 do
- FModules[i][j] := False;
- end;
- for i := 0 to 2 do
- begin
- fp := TFinderPosition(i);
- DrawFinder(fp);
- end;
- DrawAlignmentPatterns;
- DrawTimingPatterns;
- DrawDarkModule;
- ReserveFormatArea;
- ReserveVersionArea;
- DrawDataBits;
- DrawMaskPattern;
- DrawFormat;
- DrawVersion;
- end;
- procedure TQRCode.EncodeAlphaNumeric;
- function LookupAlphaVal(c : char) : integer;
- var
- i: Integer;
- begin
- Result := 0;
- for i := 0 to 44 do
- if AlphaEncoding[i] = c then
- begin
- Result := i;
- break;
- end;
- end;
- var
- sSeg : string;
- s: String;
- iVal : integer;
- begin
- s := TEncoding.UTF8.GetString(FData);
- while s.Length > 0 do
- begin
- sSeg := s.Substring(0,2);
- Delete(s,1,2);
- if sSeg.Length = 2 then
- begin
- iVal := (LookupAlphaVal(sSeg.Chars[0]) * 45)+LookupAlphaVal(sSeg.Chars[1]) ;
- WriteBits(DecimalToBinary(iVal,11));
- end else
- begin
- iVal := LookupAlphaVal(sSeg.Chars[0]);
- WriteBits(DecimalToBinary(iVal,6));
- end;
- end;
- end;
- procedure TQRCode.EncodeByte;
- var
- i: Integer;
- begin
- for i := 0 to Length(FData)-1 do
- WriteBits(DecimalToBinary(FData[i],8));
- end;
- procedure TQRCode.EncodeKanji;
- begin
- raise EQREncodeException.Create('Kanji is not currently supported.');
- end;
- procedure TQRCode.EncodeNumeric;
- var
- sSeg : string;
- s : string;
- begin
- s := TEncoding.UTF8.GetString(FData);
- while s.Length > 0 do
- begin
- sSeg := s.Substring(0,3);
- Delete(s,1,3);
- if (sSeg <> '') and sSeg.StartsWith('0') then
- Delete(sSeg,1,1);
- if (sSeg <> '') and sSeg.StartsWith('0') then
- Delete(sSeg,1,1);
- if sSeg = '' then
- sSeg := '0';
- case sSeg.Length of
- 1:
- WriteBits(DecimalToBinary(sSeg.ToInteger,4));
- 2:
- WriteBits(DecimalToBinary(sSeg.ToInteger,7));
- 3:
- WriteBits(DecimalToBinary(sSeg.ToInteger,10));
- end;
- end;
- end;
- procedure TQRCode.EndUpdate;
- begin
- dec(FUpdateDepth);
- if FUpdateDepth < 0 then
- FUpdateDepth := 0;
- if FUpdateDepth = 0 then
- UpdateCode;
- end;
- function TQRCode.DataCodewordCount: integer;
- begin
- case FECLInUse of
- TErrorCorrectionLevel.Low:
- Result := FCodeWordRequirements[FVersionInUse].Low[TCodeWordField.DataCodewordCount];
- TErrorCorrectionLevel.Medium:
- Result := FCodeWordRequirements[FVersionInUse].Medium[TCodeWordField.DataCodewordCount];
- TErrorCorrectionLevel.Quartile:
- Result := FCodeWordRequirements[FVersionInUse].Quartile[TCodeWordField.DataCodewordCount];
- TErrorCorrectionLevel.High:
- Result := FCodeWordRequirements[FVersionInUse].High[TCodeWordField.DataCodewordCount];
- else
- Result := 0;
- end;
- end;
- function TQRCode.FinderLocation(pos: TFinderPosition): TPoint;
- begin
- case pos of
- TFinderPosition.TopLeft:
- Result := TPoint.Create(0,0);
- TFinderPosition.TopRight:
- Result := TPoint.Create((((Integer(FVersionInUse)-1)*4)+21) - 7, 0);
- TFinderPosition.BottomLeft:
- Result := TPoint.Create(0,(((Integer(FVersionInUse)-1)*4)+21) - 7);
- end;
- end;
- procedure TQRCode.CalculateModules;
- var
- g1, g2, gECC1, gECC2 : TGroup;
- blk : TBlock;
- cw : Byte;
- i, iBlock, iPos, iOutPos: integer;
- cwf : TCodeWordFields;
- iECCSize : integer;
- rs : TReedSolomonGenerator;
- begin
- case FECLInUse of
- TErrorCorrectionLevel.Low:
- cwf := FCodeWordRequirements[FVersionInUse].Low;
- TErrorCorrectionLevel.Medium:
- cwf := FCodeWordRequirements[FVersionInUse].Medium;
- TErrorCorrectionLevel.Quartile:
- cwf := FCodeWordRequirements[FVersionInUse].Quartile;
- TErrorCorrectionLevel.High:
- cwf := FCodeWordRequirements[FVersionInUse].High;
- end;
- iPos := 0;
- iECCSize := 0;
- SetStatus('Collecting Data Codewords');
- setLength(g1, cwf[TCodeWordField.BlocksInGroup1Count]);
- for iBlock := 0 to Length(g1)-1 do
- begin
- setLength(blk, cwf[TCodeWordField.DataCodewordsInGroup1BlockCount]);
- for i := 0 to cwf[TCodeWordField.DataCodewordsInGroup1BlockCount]-1 do
- begin
- cw := ReadCodeword(iPos);
- blk[i] := cw;
- end;
- g1[iBlock] := blk;
- end;
- setLength(g2, cwf[TCodeWordField.BlocksInGroup2Count]);
- for iBlock := 0 to Length(g2)-1 do
- begin
- setLength(blk, cwf[TCodeWordField.DataCodewordsInGroup2BlockCount]);
- for i := 0 to cwf[TCodeWordField.DataCodewordsInGroup2BlockCount]-1 do
- begin
- cw := ReadCodeword(iPos);
- blk[i] := cw;
- end;
- g2[iBlock] := blk;
- end;
- setLength(gECC1, length(g1));
- for iBlock := 0 to length(g1)-1 do
- begin
- SetStatus('Calculating ECC Codewords Group 1 Block '+(iBlock+1).ToString);
- blk := g1[iBlock];
- inc(iECCSize, cwf[TCodeWordField.ECCodewordsPerBlock]);
- rs := TReedSolomonGenerator.Create(cwf[TCodeWordField.ECCodewordsPerBlock]);
- try
- gECC1[iBlock] := rs.GetRemaineder(blk);
- finally
- rs.Free;
- end;
- end;
- setLength(gECC2, length(g2));
- for iBlock := 0 to length(g2)-1 do
- begin
- SetStatus('Calculating ECC Codewords Group 2 Block '+(iBlock+1).ToString);
- blk := g2[iBlock];
- inc(iECCSize, cwf[TCodeWordField.ECCodewordsPerBlock]);
- rs := TReedSolomonGenerator.Create(cwf[TCodeWordField.ECCodewordsPerBlock]);
- try
- gECC2[iBlock] := rs.GetRemaineder(blk);
- finally
- rs.Free;
- end;
- end;
- SetStatus('Interleaving Data Codewords');
- SetLength(FCodeWords, CodewordCount+iECCSize);
- iPos := 0;
- iOutPos := 0;
- repeat
- if length(g1) > 0 then
- begin
- if iPos < cwf[TCodeWordField.DataCodewordsInGroup1BlockCount] then
- for iBlock := 0 to length(g1)-1 do
- begin
- if iPos < length(g1[iBlock]) then
- begin
- FCodeWords[iOutPos] := g1[iBlock][iPos];
- inc(iOutPos);
- end;
- end;
- end;
- if length(g2) > 0 then
- begin
- if iPos < cwf[TCodeWordField.DataCodewordsInGroup2BlockCount] then
- for iBlock := 0 to length(g2)-1 do
- begin
- if iPos < length(g2[iBlock]) then
- begin
- FCodeWords[iOutPos] := g2[iBlock][iPos];
- inc(iOutPos);
- end;
- end;
- end;
- inc(iPos);
- until iOutPos >= (Length(FCodeWords)-iECCSize);
- SetStatus('Interleaving ECC Codewords');
- iPos := 0;
- repeat
- if length(gECC1) > 0 then
- begin
- if iPos < cwf[TCodeWordField.ECCodewordsPerBlock] then
- for iBlock := 0 to length(gECC1)-1 do
- begin
- if iPos < length(gECC1[iBlock]) then
- begin
- FCodeWords[iOutPos] := gECC1[iBlock][iPos];
- inc(iOutPos);
- end;
- end;
- end;
- if length(gECC2) > 0 then
- begin
- if iPos < cwf[TCodeWordField.ECCodewordsPerBlock] then
- for iBlock := 0 to length(gECC2)-1 do
- begin
- if iPos < length(gECC2[iBlock]) then
- begin
- FCodeWords[iOutPos] := gECC2[iBlock][iPos];
- inc(iOutPos);
- end;
- end;
- end;
- inc(iPos);
- until iOutPos >= Length(FCodeWords);
- FDataBits := OutputAsString;
- for i := 1 to RemainderBits[FVersionInUse] do
- begin
- FDataBits := FDataBits + '0';
- end;
- SetStatus('Drawing Modules');
- DrawModules;
- end;
- function TQRCode.GetText: string;
- begin
- Result := TEncoding.UTF8.GetString(FData);
- end;
- function TQRCode.MaxECL: TErrorCorrectionLevel;
- begin
- if Length(FData) < FVerCapacities[FVersionInUse].High[FMode] then
- Exit(TErrorCorrectionLevel.High)
- else if Length(FData) < FVerCapacities[FVersionInUse].Quartile[FMode] then
- Exit(TErrorCorrectionLevel.Quartile)
- else if Length(FData) < FVerCapacities[FVersionInUse].Medium[FMode] then
- Exit(TErrorCorrectionLevel.Medium)
- else if length(FData) < FVerCapacities[FVersionInUse].Low[FMode] then
- Exit(TErrorCorrectionLevel.Low)
- else
- raise Exception.Create('The data supplied will not fit in the requested qr version.');
- end;
- function TQRCode.MinVersion : TVersion;
- var
- iLen : integer;
- i : TVersion;
- s : string;
- begin
- s := TEncoding.UTF8.GetString(FData);
- iLen := Length(S);
- for i := TVersion.v1 to TVersion.v40 do
- begin
- Result := i;
- case FECLInUse of
- TErrorCorrectionLevel.Low:
- if iLen <= FVerCapacities[i].Low[Mode] then
- break;
- TErrorCorrectionLevel.Medium:
- if iLen <= FVerCapacities[i].Medium[Mode] then
- break;
- TErrorCorrectionLevel.Quartile:
- if iLen <= FVerCapacities[i].Quartile[Mode] then
- break;
- TErrorCorrectionLevel.High:
- if iLen <= FVerCapacities[i].High[Mode] then
- break;
- end;
- end;
- end;
- function TQRCode.OutputAsString: string;
- var
- i: Integer;
- begin
- Result := '';
- for i := 0 to Length(FCodeWords)-1 do
- begin
- Result := Result+DecimalToBinary(FCodeWords[i],8);
- end;
- end;
- procedure TQRCode.PaintQRCode;
- var
- x, y, width : integer;
- Offset : integer;
- FilledRects : TArray<TRect>;
- iCnt : integer;
- begin
- if not Assigned(FOnPaint) then
- exit;
- width := (Length(FModules) * FPixelsPerModule) + (8 * FPixelsPerModule) + 2;
- Offset := (4 * FPixelsPerModule)+1; // Quiet Zone
- x := 0;
- y := 0;
- iCnt := 0;
- setLength(FilledRects, Size * Size);
- repeat
- repeat
- if FModules[x][y] then
- begin
- FilledRects[iCnt] :=
- TRect.Create(
- (x*FPixelsPerModule)+Offset,
- (y*FPixelsPerModule)+Offset,
- (x*FPixelsPerModule)+FPixelsPerModule+Offset,
- (y*FPixelsPerModule)+FPixelsPerModule+Offset
- );
- inc(iCnt);
- end;
- inc(y);
- until y = Length(FModules[x]);
- y := 0;
- inc(x);
- until x = Length(FModules);
- SetLength(FilledRects, iCnt);
- FOnPaint(width, width, FilledRects);
- end;
- function TQRCode.Pow(i, k: Integer): Integer;
- var
- j, Count: Integer;
- begin
- if k>0 then j:=2
- else j:=1;
- for Count:=1 to k-1 do
- j:=j*i;
- Result:=j;
- end;
- function TQRCode.GetSize: integer;
- begin
- Result := (((Integer(FVersionInUse)-1)*4)+21);
- end;
- function TQRCode.ReadCodeword(var Pos: integer): Byte;
- var
- s : string;
- iCnt : integer;
- begin
- iCnt := 0;
- s := '';
- repeat
- if FBits[Pos] then
- s := s+'1'
- else
- s := s+'0';
- inc(iCnt);
- inc(Pos);
- until (Pos > FBitsPos) or (iCnt >= 8);
- Result := BinaryToDecimal(s);
- end;
- procedure TQRCode.Redraw;
- begin
- UpdateCode;
- end;
- procedure TQRCode.SetData(const Value: TArray<Byte>);
- begin
- FData := Value;
- UpdateCode;
- end;
- procedure TQRCode.SetECL(const Value: TErrorCorrectionLevel);
- begin
- FECL := Value;
- if FECL <> TErrorCorrectionLevel.Auto then
- FECLInUse := Value;
- UpdateCode;
- end;
- procedure TQRCode.SetMask(const Value: TMask);
- begin
- FMask := Value;
- UpdateCode;
- end;
- procedure TQRCode.SetOnPaint(const Value: TPaintHandler);
- begin
- FOnPaint := Value;
- UpdateCode;
- end;
- procedure TQRCode.SetPixelsPerModule(const Value: integer);
- begin
- if Value <= 0 then
- raise Exception.Create('PixelsPerModule cannot be sero or less.');
- FPixelsPerModule := Value;
- FRenderSize := FPixelsPerModule * Size;
- UpdateCode;
- end;
- procedure TQRCode.SetRenderSize(const Value: integer);
- begin
- PixelsPerModule := Value div (Size+8);
- end;
- procedure TQRCode.SetStatus(const Msg: string);
- begin
- if Assigned(FOnStatus) then
- FOnStatus(Msg);
- end;
- procedure TQRCode.SetText(const Value: string);
- begin
- FData := TEncoding.UTF8.GetBytes(Value);
- UpdateCode;
- end;
- procedure TQRCode.SetVersion(const Value: TVersion);
- begin
- FVersion := Value;
- if FVersion <> TVersion.Auto then
- FVersionInUse := Value;
- UpdateCode;
- end;
- procedure TQRCode.UpdateCode;
- var
- iReqBits : integer;
- i: Integer;
- begin
- if FUpdateDepth > 0 then
- exit;
- SetLength(FBits, 0);
- SetLength(FBits, 4096);
- FBitsLen := 4096;
- FBitsPos := 0;
- FReservedAreas.Clear;
- FMode := DetermineQRMode;
- if FVersion = TVersion.Auto then
- FVersionInUse := MinVersion
- else
- while (FVersionInUse < MinVersion) do
- if (FECLInUse > TErrorCorrectionLevel.Low) and (FECL = TErrorCorrectionLevel.Auto) then
- begin
- Dec(FECLInUse);
- end else
- raise EQREncodeException.Create('Specified Version is too low for size of data to encode.');
- if FECL = TErrorCorrectionLevel.Auto then
- FECLInUse := MaxECL
- else
- while FECL > MaxECL do
- begin
- if (FVersionInUse < TVersion.v40) and (FVersion = TVersion.Auto) then
- inc(FVersionInUse)
- else
- raise EQREncodeException.Create('Specified Error Correction Level is too high for this qr code version and data size.');
- end;
- SetStatus('Initializing Bits');
- WriteMode;
- WriteLength;
- SetStatus('Encoding Data');
- case FMode of
- TQRMode.Numeric:
- EncodeNumeric;
- TQRMode.AlphaNumeric:
- EncodeAlphaNumeric;
- TQRMode.Byte:
- EncodeByte;
- TQRMode.Kanji:
- EncodeKanji;
- end;
- iReqBits := DataCodewordCount * 8;
- for i := 1 to 4 do
- begin
- if FBitsPos < iReqBits then
- WriteBit(False);
- end;
- while (FBitsPos mod 8) <> 0 do
- WriteBit(False);
- while FBitsPos < iReqBits do
- begin
- WriteBits('11101100');
- if FBitsPos < iReqBits then
- WriteBits('00010001');
- end;
- SetStatus('Calculating Modules');
- CalculateModules;
- SetStatus('Painting Code');
- PaintQRCode;
- end;
- procedure TQRCode.WriteBit(b: boolean);
- begin
- FBits[FBitsPos] := b ;
- inc(FBitsPos);
- CheckBitsPos;
- end;
- procedure TQRCode.WriteBits(const s: string);
- var
- c: Char;
- begin
- for c in s do
- begin
- if c = '0' then
- WriteBit(False)
- else if c = '1' then
- WriteBit(True)
- else
- raise Exception.Create('Bad Bit');
- end;
- end;
- procedure TQRCode.WriteLength;
- var
- s : string;
- iBits : integer;
- begin
- case FVersionInUse of
- TVersion.v1..TVersion.v9:
- case FMode of
- TQRMode.Numeric:
- iBits := 10;
- TQRMode.AlphaNumeric:
- iBits := 9;
- TQRMode.Byte:
- iBits := 8;
- TQRMode.Kanji:
- iBits := 8;
- else
- iBits := 0;
- end;
- TVersion.v10..TVersion.v26:
- case FMode of
- TQRMode.Numeric:
- iBits := 12;
- TQRMode.AlphaNumeric:
- iBits := 11;
- TQRMode.Byte:
- iBits := 16;
- TQRMode.Kanji:
- iBits := 10;
- else
- iBits := 0;
- end;
- TVersion.v27..TVersion.v40:
- case FMode of
- TQRMode.Numeric:
- iBits := 14;
- TQRMode.AlphaNumeric:
- iBits := 13;
- TQRMode.Byte:
- iBits := 16;
- TQRMode.Kanji:
- iBits := 12;
- else
- iBits := 0;
- end;
- else
- iBits := 0;
- end;
- s := DecimalToBinary(length(FData), iBits);
- while length(s) < iBits do
- s := '0'+s;
- WriteBits(s);
- end;
- procedure TQRCode.WriteMode;
- begin
- case FMode of
- TQRMode.Numeric:
- WriteBits('0001');
- TQRMode.AlphaNumeric:
- WriteBits('0010');
- TQRMode.Byte:
- WriteBits('0100');
- TQRMode.Kanji:
- WriteBits('1000');
- end;
- end;
- { TQRCode.TArrayHelper<T> }
- class function TQRCode.TArrayHelper<T>.AdvanceArray(Source: TArray<T>;
- idx: integer): TArray<T>;
- var
- i: Integer;
- begin
- SetLength(Result,Length(Source)-idx);
- for i := 0 to Length(Result)-1 do
- Result[i] := Source[i+idx];
- end;
- class function TQRCode.TArrayHelper<T>.Combination(SourceArray: TArray<T>;
- SubsetSize: Cardinal): TArray<TArray<T>>;
- var
- i, iResultSize, iNum, iDenom : Cardinal;
- idx: Cardinal;
- ary : TArray<T>;
- begin
- iNum := 1;
- iDenom := 1;
- for i := Length(SourceArray) downto Length(SourceArray)-SubsetSize+1 do
- iNum := iNum*i;
- for i := SubsetSize downto 1 do
- iDenom := iDenom*i;
- iResultSize := iNum div iDenom;
- SetLength(Result, iResultSize);
- SetLength(ary,0);
- idx := 0;
- NextCombo(ary, SourceArray, SubsetSize, Result, idx);
- end;
- class procedure TQRCode.TArrayHelper<T>.NextCombo(Prefix, Source: TArray<T>;
- Count: Cardinal; Result: TArray<TArray<T>>; var ResultIdx: Cardinal);
- var
- i : integer;
- a: T;
- ary : TArray<T>;
- begin
- if Count = 0 then
- begin
- Result[ResultIdx] := Prefix;
- inc(ResultIdx);
- exit;
- end;
- for i := 0 to length(Source)-1 do
- begin
- a := Source[i];
- ary := Prefix;
- SetLength(ary,Length(ary)+1);
- ary[Length(ary)-1] := a;
- NextCombo(ary, AdvanceArray(Source,i+1), Count-1,Result,ResultIdx);
- end;
- end;
- { TQRCode.TRectHelper }
- function TQRCode.TRectHelper.IntersectsWithPoint(const pt: TPoint): boolean;
- begin
- Result := IntersectsWithRect(TRect.Create(pt.X, pt.Y, pt.X, pt.Y));
- end;
- function TQRCode.TRectHelper.IntersectsWithRect(const R: TRect): boolean;
- begin
- Result := (Self.Left <= R.Right)
- and (Self.Right >= R.Left)
- and (Self.Top <= R.Bottom)
- and (Self.Bottom >= R.Top);
- end;
- end.
|