qr.code.pas 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973
  1. //Copyright (c) 2019 by Jason Southwell
  2. //
  3. //Permission is hereby granted, free of charge, to any person obtaining a copy
  4. //of this software and associated documentation files (the "Software"), to deal
  5. //in the Software without restriction, including without limitation the rights
  6. //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. //copies of the Software, and to permit persons to whom the Software is
  8. //furnished to do so, subject to the following conditions:
  9. //
  10. //The above copyright notice and this permission notice shall be included in all
  11. //copies or substantial portions of the Software.
  12. //
  13. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. //SOFTWARE.
  20. unit qr.code;
  21. interface
  22. uses System.SysUtils, System.Classes, System.Generics.Collections, System.Types;
  23. {$SCOPEDENUMS ON}
  24. type
  25. TQRMode = (Numeric, AlphaNumeric, Byte, Kanji);
  26. TErrorCorrectionLevel = (Auto, Low, Medium, Quartile, High);
  27. TVersion = ( Auto,
  28. v1, v2, v3, v4, v5, v6, v7, v8, v9,
  29. v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
  30. v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
  31. v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
  32. v40);
  33. TMask = (m0, m1, m2, m3, m4, m5, m6, m7, Auto);
  34. TPaintHandler = reference to procedure(Width, Height : integer; BlackRects : TArray<TRect>);
  35. TOnStatusHandler = reference to procedure(const Msg : String);
  36. EQREncodeException = Exception;
  37. TQRCode = class(TPersistent)
  38. strict private
  39. type
  40. TBlock = TArray<Byte>;
  41. TGroup = TArray<TBlock>;
  42. TFinderPosition = (TopLeft, TopRight, BottomLeft);
  43. TCodeWordField = (DataCodewordCount, ECCodewordsPerBlock, BlocksInGroup1Count, DataCodewordsInGroup1BlockCount, BlocksInGroup2Count, DataCodewordsInGroup2BlockCount);
  44. TCodeWordFields = Array[TCodeWordField] of integer;
  45. TCodeWordRequirements = record
  46. Low : TCodeWordFields;
  47. Medium : TCodeWordFields;
  48. Quartile : TCodeWordFields;
  49. High : TCodeWordFields;
  50. end;
  51. TCapacities = record
  52. Low : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
  53. Medium : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
  54. Quartile : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
  55. High : Array[TQRMode.Numeric..TQRMode.Kanji] of Integer;
  56. end;
  57. TRectHelper = record helper for TRect
  58. function IntersectsWithRect(const R : TRect) : boolean;
  59. function IntersectsWithPoint(const pt : TPoint) : boolean;
  60. end;
  61. TArrayHelper<T> = class
  62. strict private
  63. class procedure NextCombo(Prefix, Source: TArray<T>; Count: Cardinal;
  64. Result: TArray<TArray<T>>; var ResultIdx: Cardinal); static;
  65. public
  66. class function AdvanceArray(Source: TArray<T>; idx: integer): TArray<T>;
  67. class function Combination(SourceArray : TArray<T>; SubsetSize : Cardinal) : TArray<TArray<T>>;
  68. end;
  69. strict private
  70. class var FVerCapacities : Array[TVersion.v1..TVersion.v40] of TCapacities;
  71. class var FCodeWordRequirements : Array[TVersion.v1..TVersion.v40] of TCodeWordRequirements;
  72. strict private
  73. FOnStatus: TOnStatusHandler;
  74. FPenaltyScores: TArray<TArray<Integer>>;
  75. FMaskInUse: TMask;
  76. FVersion: TVersion;
  77. FVersionInUse : TVersion;
  78. FMode: TQRMode;
  79. FECL: TErrorCorrectionLevel;
  80. FECLInUse : TErrorCorrectionLevel;
  81. FData: TArray<Byte>;
  82. FUpdateDepth : integer;
  83. FCodeWords : TArray<Byte>;
  84. FReservedAreas : TList<TRect>;
  85. FBitsLen : integer;
  86. FBitsPos : integer;
  87. FBits : TArray<Boolean>;
  88. FLogTable : TArray<Byte>;
  89. FAntilogTable : TArray<Byte>;
  90. FModules : TArray<TArray<Boolean>>;
  91. FPixelsPerModule: Integer;
  92. FDataBits : string;
  93. FMask : TMask;
  94. FRenderSize: integer;
  95. FOnPaint: TPaintHandler;
  96. procedure SetOnPaint(const Value: TPaintHandler);
  97. procedure SetPixelsPerModule(const Value: integer);
  98. procedure SetRenderSize(const Value: integer);
  99. function GetText: string;
  100. procedure SetData(const Value: TArray<Byte>);
  101. procedure SetECL(const Value: TErrorCorrectionLevel);
  102. procedure SetText(const Value: string);
  103. procedure SetVersion(const Value: TVersion);
  104. procedure SetMask(const Value: TMask);
  105. function Pow(i, k: Integer): Integer;
  106. function BinaryToDecimal(Str: string): Integer;
  107. function DecimalToBinary(value, digits: integer): string;
  108. function DataCodewordCount : integer;
  109. function GetSize : integer;
  110. function FinderLocation(pos : TFinderPosition) : TPoint;
  111. procedure CheckBitsPos;
  112. function DetermineQRMode : TQRMode;
  113. procedure WriteMode;
  114. procedure WriteLength;
  115. function MinVersion : TVersion;
  116. function MaxECL : TErrorCorrectionLevel;
  117. procedure WriteBits(const s : string);
  118. procedure WriteBit(b : boolean);
  119. procedure CalculateModules;
  120. procedure EncodeNumeric;
  121. procedure EncodeAlphaNumeric;
  122. procedure EncodeByte;
  123. procedure EncodeKanji;
  124. function ReadCodeword(var Pos : integer) : Byte;
  125. function CodewordCount : integer;
  126. function OutputAsString : string;
  127. procedure DrawModules;
  128. procedure PaintQRCode;
  129. procedure AddReservedArea(rect : TRect);
  130. protected
  131. procedure UpdateCode; virtual;
  132. procedure SetStatus(const Msg : string); virtual;
  133. public
  134. destructor Destroy; override;
  135. constructor Create; virtual;
  136. class constructor Create;
  137. property OnPaint : TPaintHandler read FOnPaint write SetOnPaint;
  138. property OnStatus : TOnStatusHandler read FOnStatus write FOnStatus;
  139. property Mode : TQRMode read FMode;
  140. property VersionInUse : TVersion read FVersionInUse;
  141. property Data : TArray<Byte> read FData write SetData;
  142. property ECLInUse : TErrorCorrectionLEvel read FECLInUse;
  143. property DataBits : string read FDataBits;
  144. property MaskInUse : TMask read FMaskInUse;
  145. property Size : integer read GetSize;
  146. property PenaltyScores : TArray<TArray<Integer>> Read FPenaltyScores;
  147. procedure BeginUpdate;
  148. procedure EndUpdate;
  149. procedure Redraw;
  150. property Codewords : TArray<Byte> read FCodeWords;
  151. published
  152. property Version : TVersion read FVersion write SetVersion;
  153. property Text : string read GetText write SetText;
  154. property ECL : TErrorCorrectionLevel read FECL write SetECL;
  155. property Mask : TMask read FMask write SetMask;
  156. property RenderSize : integer read FRenderSize write SetRenderSize;
  157. property PixelsPerModule : integer read FPixelsPerModule write SetPixelsPerModule;
  158. end;
  159. implementation
  160. uses System.Math, qr.rs;
  161. const
  162. RemainderBits : Array[TVersion.v1..TVersion.v40] of Byte = (
  163. 0,
  164. 7,
  165. 7,
  166. 7,
  167. 7,
  168. 7,
  169. 0,
  170. 0,
  171. 0,
  172. 0,
  173. 0,
  174. 0,
  175. 0,
  176. 3,
  177. 3,
  178. 3,
  179. 3,
  180. 3,
  181. 3,
  182. 3,
  183. 4,
  184. 4,
  185. 4,
  186. 4,
  187. 4,
  188. 4,
  189. 4,
  190. 3,
  191. 3,
  192. 3,
  193. 3,
  194. 3,
  195. 3,
  196. 3,
  197. 0,
  198. 0,
  199. 0,
  200. 0,
  201. 0,
  202. 0
  203. );
  204. AlphaEncoding : Array[0..44] of char = (
  205. '0',
  206. '1',
  207. '2',
  208. '3',
  209. '4',
  210. '5',
  211. '6',
  212. '7',
  213. '8',
  214. '9',
  215. 'A',
  216. 'B',
  217. 'C',
  218. 'D',
  219. 'E',
  220. 'F',
  221. 'G',
  222. 'H',
  223. 'I',
  224. 'J',
  225. 'K',
  226. 'L',
  227. 'M',
  228. 'N',
  229. 'O',
  230. 'P',
  231. 'Q',
  232. 'R',
  233. 'S',
  234. 'T',
  235. 'U',
  236. 'V',
  237. 'W',
  238. 'X',
  239. 'Y',
  240. 'Z',
  241. ' ',
  242. '$',
  243. '%',
  244. '*',
  245. '+',
  246. '-',
  247. '.',
  248. '/',
  249. ':'
  250. );
  251. { TQRCode }
  252. procedure TQRCode.AddReservedArea(rect: TRect);
  253. begin
  254. FReservedAreas.Add(rect);
  255. end;
  256. procedure TQRCode.BeginUpdate;
  257. begin
  258. inc(FUpdateDepth);
  259. end;
  260. function TQRCode.BinaryToDecimal(Str: string): Integer;
  261. var
  262. Len, i: Integer;
  263. begin
  264. Len := Length(Str);
  265. Result := 0;
  266. for i:=1 to Len do
  267. if (Str[i]='0') or (Str[i]='1') then
  268. Result := Result + Pow(2, Len-i) * StrToInt(Str[i])
  269. else
  270. raise EQREncodeException.Create('"'+str+'" is not a binary number');
  271. end;
  272. procedure TQRCode.CheckBitsPos;
  273. begin
  274. if FBitsLen-FBitsPos < 1024 then
  275. begin
  276. inc(FBitsLen, 4096);
  277. SetLength(FBits, FBitsLen);
  278. end;
  279. end;
  280. function TQRCode.CodewordCount: integer;
  281. begin
  282. Result := FBitsPos div 8;
  283. end;
  284. class constructor TQRCode.Create;
  285. procedure AssignCodeWords(Elim : integer; Level : TErrorCorrectionLevel; DCC, ECCPerBlock, BG1, DG1C, BG2, DG2C : integer); overload;
  286. begin
  287. case Level of
  288. TErrorCorrectionLevel.Low:
  289. begin
  290. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordCount] := DCC;
  291. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
  292. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.BlocksInGroup1Count] := BG1;
  293. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
  294. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.BlocksInGroup2Count] := BG2;
  295. FCodeWordRequirements[TVersion(Elim)].Low[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
  296. end;
  297. TErrorCorrectionLevel.Medium:
  298. begin
  299. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordCount] := DCC;
  300. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
  301. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.BlocksInGroup1Count] := BG1;
  302. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
  303. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.BlocksInGroup2Count] := BG2;
  304. FCodeWordRequirements[TVersion(Elim)].Medium[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
  305. end;
  306. TErrorCorrectionLevel.Quartile:
  307. begin
  308. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordCount] := DCC;
  309. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
  310. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.BlocksInGroup1Count] := BG1;
  311. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
  312. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.BlocksInGroup2Count] := BG2;
  313. FCodeWordRequirements[TVersion(Elim)].Quartile[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
  314. end;
  315. TErrorCorrectionLevel.High:
  316. begin
  317. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordCount] := DCC;
  318. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.ECCodewordsPerBlock] := ECCPerBlock;
  319. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.BlocksInGroup1Count] := BG1;
  320. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordsInGroup1BlockCount] := DG1C;
  321. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.BlocksInGroup2Count] := BG2;
  322. FCodeWordRequirements[TVersion(Elim)].High[TCodeWordField.DataCodewordsInGroup2BlockCount] := DG2C;
  323. end;
  324. end;
  325. end;
  326. procedure AssignCodeWords(Elim : integer; Level : TErrorCorrectionLevel; DCC, ECCPerBlock, BG1, DG1C : integer); overload;
  327. begin
  328. AssignCodeWords(Elim, Level, DCC, ECCPerBlock, BG1, DG1C, 0, 0);
  329. end;
  330. procedure AssignVerCapacity(Elim : integer; Level : TErrorCorrectionLevel; Num, Alph, Byt, Kanj : integer);
  331. begin
  332. case Level of
  333. TErrorCorrectionLevel.Low:
  334. begin
  335. FVerCapacities[TVersion(Elim)].Low[TQRMode.Numeric] := Num;
  336. FVerCapacities[TVersion(Elim)].Low[TQRMode.AlphaNumeric] := Alph;
  337. FVerCapacities[TVersion(Elim)].Low[TQRMode.Byte] := Byt;
  338. FVerCapacities[TVersion(Elim)].Low[TQRMode.Kanji] := Kanj;
  339. end;
  340. TErrorCorrectionLevel.Medium:
  341. begin
  342. FVerCapacities[TVersion(Elim)].Medium[TQRMode.Numeric] := Num;
  343. FVerCapacities[TVersion(Elim)].Medium[TQRMode.AlphaNumeric] := Alph;
  344. FVerCapacities[TVersion(Elim)].Medium[TQRMode.Byte] := Byt;
  345. FVerCapacities[TVersion(Elim)].Medium[TQRMode.Kanji] := Kanj;
  346. end;
  347. TErrorCorrectionLevel.Quartile:
  348. begin
  349. FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Numeric] := Num;
  350. FVerCapacities[TVersion(Elim)].Quartile[TQRMode.AlphaNumeric] := Alph;
  351. FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Byte] := Byt;
  352. FVerCapacities[TVersion(Elim)].Quartile[TQRMode.Kanji] := Kanj;
  353. end;
  354. TErrorCorrectionLevel.High:
  355. begin
  356. FVerCapacities[TVersion(Elim)].High[TQRMode.Numeric] := Num;
  357. FVerCapacities[TVersion(Elim)].High[TQRMode.AlphaNumeric] := Alph;
  358. FVerCapacities[TVersion(Elim)].High[TQRMode.Byte] := Byt;
  359. FVerCapacities[TVersion(Elim)].High[TQRMode.Kanji] := Kanj;
  360. end;
  361. end;
  362. end;
  363. begin
  364. AssignVerCapacity(1 ,TErrorCorrectionLevel.Low ,41 ,25 ,17 ,10);
  365. AssignVerCapacity(1 ,TErrorCorrectionLevel.Medium, 34 , 20 , 14 , 8);
  366. AssignVerCapacity(1 ,TErrorCorrectionLevel.Quartile, 27 , 16 , 11 , 7);
  367. AssignVerCapacity(1 ,TErrorCorrectionLevel.High, 17 , 10 , 7, 4);
  368. AssignVerCapacity(2 ,TErrorCorrectionLevel.Low ,77 ,47 ,32 ,20);
  369. AssignVerCapacity(2 ,TErrorCorrectionLevel.Medium, 63 , 38 , 26 , 16);
  370. AssignVerCapacity(2 ,TErrorCorrectionLevel.Quartile, 48 , 29 , 20 , 12);
  371. AssignVerCapacity(2 ,TErrorCorrectionLevel.High, 34 , 20 , 14 , 8);
  372. AssignVerCapacity(3 ,TErrorCorrectionLevel.Low ,127 ,77 ,53 ,32);
  373. AssignVerCapacity(3 ,TErrorCorrectionLevel.Medium, 101, 61 , 42 , 26);
  374. AssignVerCapacity(3 ,TErrorCorrectionLevel.Quartile, 77 , 47 , 32 , 20);
  375. AssignVerCapacity(3 ,TErrorCorrectionLevel.High, 58 , 35 , 24 , 15);
  376. AssignVerCapacity(4 ,TErrorCorrectionLevel.Low ,187 ,114 ,78 ,48);
  377. AssignVerCapacity(4 ,TErrorCorrectionLevel.Medium, 149, 90 , 62 , 38);
  378. AssignVerCapacity(4 ,TErrorCorrectionLevel.Quartile, 111, 67 , 46 , 28);
  379. AssignVerCapacity(4 ,TErrorCorrectionLevel.High, 82 , 50 , 34 , 21);
  380. AssignVerCapacity(5 ,TErrorCorrectionLevel.Low ,255 ,154 ,106 ,65);
  381. AssignVerCapacity(5 ,TErrorCorrectionLevel.Medium, 202, 122, 84 , 52);
  382. AssignVerCapacity(5 ,TErrorCorrectionLevel.Quartile, 144, 87 , 60 , 37);
  383. AssignVerCapacity(5 ,TErrorCorrectionLevel.High, 106, 64 , 44 , 27);
  384. AssignVerCapacity(6 ,TErrorCorrectionLevel.Low ,322 ,195 ,134 ,82);
  385. AssignVerCapacity(6 ,TErrorCorrectionLevel.Medium, 255, 154, 106, 65);
  386. AssignVerCapacity(6 ,TErrorCorrectionLevel.Quartile, 178, 108, 74 , 45);
  387. AssignVerCapacity(6 ,TErrorCorrectionLevel.High, 139, 84 , 58 , 36);
  388. AssignVerCapacity(7 ,TErrorCorrectionLevel.Low ,370 ,224 ,154 ,95);
  389. AssignVerCapacity(7 ,TErrorCorrectionLevel.Medium, 293, 178, 122, 75);
  390. AssignVerCapacity(7 ,TErrorCorrectionLevel.Quartile, 207, 125, 86 , 53);
  391. AssignVerCapacity(7 ,TErrorCorrectionLevel.High, 154, 93 , 64 , 39);
  392. AssignVerCapacity(8 ,TErrorCorrectionLevel.Low ,461 ,279 ,192 ,118);
  393. AssignVerCapacity(8 ,TErrorCorrectionLevel.Medium, 365, 221, 152, 93);
  394. AssignVerCapacity(8 ,TErrorCorrectionLevel.Quartile, 259, 157, 108, 66);
  395. AssignVerCapacity(8 ,TErrorCorrectionLevel.High, 202, 122, 84 , 52);
  396. AssignVerCapacity(9 ,TErrorCorrectionLevel.Low ,552 ,335 ,230 ,141);
  397. AssignVerCapacity(9 ,TErrorCorrectionLevel.Medium, 432, 262, 180, 111);
  398. AssignVerCapacity(9 ,TErrorCorrectionLevel.Quartile, 312, 189, 130, 80);
  399. AssignVerCapacity(9 ,TErrorCorrectionLevel.High, 235, 143, 98 , 60);
  400. AssignVerCapacity(10 ,TErrorCorrectionLevel.Low ,652 ,395 ,271 ,167);
  401. AssignVerCapacity(10 ,TErrorCorrectionLevel.Medium, 513, 311, 213, 131);
  402. AssignVerCapacity(10 ,TErrorCorrectionLevel.Quartile, 364, 221, 151, 93);
  403. AssignVerCapacity(10 ,TErrorCorrectionLevel.High, 288, 174, 119, 74);
  404. AssignVerCapacity(11 ,TErrorCorrectionLevel.Low ,772 ,468 ,321 ,198);
  405. AssignVerCapacity(11 ,TErrorCorrectionLevel.Medium, 604, 366, 251, 155);
  406. AssignVerCapacity(11 ,TErrorCorrectionLevel.Quartile, 427, 259, 177, 109);
  407. AssignVerCapacity(11 ,TErrorCorrectionLevel.High, 331, 200, 137, 85);
  408. AssignVerCapacity(12 ,TErrorCorrectionLevel.Low ,883 ,535 ,367 ,226);
  409. AssignVerCapacity(12 ,TErrorCorrectionLevel.Medium, 691, 419, 287, 177);
  410. AssignVerCapacity(12 ,TErrorCorrectionLevel.Quartile, 489, 296, 203, 125);
  411. AssignVerCapacity(12 ,TErrorCorrectionLevel.High, 374, 227, 155, 96);
  412. AssignVerCapacity(13 ,TErrorCorrectionLevel.Low ,1022 ,619 ,425 ,262);
  413. AssignVerCapacity(13 ,TErrorCorrectionLevel.Medium, 796, 483, 331, 204);
  414. AssignVerCapacity(13 ,TErrorCorrectionLevel.Quartile, 580, 352, 241, 149);
  415. AssignVerCapacity(13 ,TErrorCorrectionLevel.High, 427, 259, 177, 109);
  416. AssignVerCapacity(14 ,TErrorCorrectionLevel.Low ,1101 ,667 ,458 ,282);
  417. AssignVerCapacity(14 ,TErrorCorrectionLevel.Medium, 871, 528, 362, 223);
  418. AssignVerCapacity(14 ,TErrorCorrectionLevel.Quartile, 621, 376, 258, 159);
  419. AssignVerCapacity(14 ,TErrorCorrectionLevel.High, 468, 283, 194, 120);
  420. AssignVerCapacity(15 ,TErrorCorrectionLevel.Low ,1250 ,758 ,520 ,320);
  421. AssignVerCapacity(15 ,TErrorCorrectionLevel.Medium, 991, 600, 412, 254);
  422. AssignVerCapacity(15 ,TErrorCorrectionLevel.Quartile, 703, 426, 292, 180);
  423. AssignVerCapacity(15 ,TErrorCorrectionLevel.High, 530, 321, 220, 136);
  424. AssignVerCapacity(16 ,TErrorCorrectionLevel.Low ,1408 ,854 ,586 ,361);
  425. AssignVerCapacity(16 ,TErrorCorrectionLevel.Medium, 1082 , 656, 450, 277);
  426. AssignVerCapacity(16 ,TErrorCorrectionLevel.Quartile, 775, 470, 322, 198);
  427. AssignVerCapacity(16 ,TErrorCorrectionLevel.High, 602, 365, 250, 154);
  428. AssignVerCapacity(17 ,TErrorCorrectionLevel.Low ,1548 ,938 ,644 ,397);
  429. AssignVerCapacity(17 ,TErrorCorrectionLevel.Medium, 1212 , 734, 504, 310);
  430. AssignVerCapacity(17 ,TErrorCorrectionLevel.Quartile, 876, 531, 364, 224);
  431. AssignVerCapacity(17 ,TErrorCorrectionLevel.High, 674, 408, 280, 173);
  432. AssignVerCapacity(18 ,TErrorCorrectionLevel.Low ,1725 ,1046 ,718 ,442);
  433. AssignVerCapacity(18 ,TErrorCorrectionLevel.Medium, 1346 , 816, 560, 345);
  434. AssignVerCapacity(18 ,TErrorCorrectionLevel.Quartile, 948, 574, 394, 243);
  435. AssignVerCapacity(18 ,TErrorCorrectionLevel.High, 746, 452, 310, 191);
  436. AssignVerCapacity(19 ,TErrorCorrectionLevel.Low ,1903 ,1153 ,792 ,488);
  437. AssignVerCapacity(19 ,TErrorCorrectionLevel.Medium, 1500 , 909, 624, 384);
  438. AssignVerCapacity(19 ,TErrorCorrectionLevel.Quartile, 1063 , 644, 442, 272);
  439. AssignVerCapacity(19 ,TErrorCorrectionLevel.High, 813, 493, 338, 208);
  440. AssignVerCapacity(20 ,TErrorCorrectionLevel.Low ,2061 ,1249 ,858 ,528);
  441. AssignVerCapacity(20 ,TErrorCorrectionLevel.Medium, 1600 , 970, 666, 410);
  442. AssignVerCapacity(20 ,TErrorCorrectionLevel.Quartile, 1159 , 702, 482, 297);
  443. AssignVerCapacity(20 ,TErrorCorrectionLevel.High, 919, 557, 382, 235);
  444. AssignVerCapacity(21 ,TErrorCorrectionLevel.Low ,2232 ,1352 ,929 ,572);
  445. AssignVerCapacity(21 ,TErrorCorrectionLevel.Medium, 1708 , 1035 , 711, 438);
  446. AssignVerCapacity(21 ,TErrorCorrectionLevel.Quartile, 1224 , 742, 509, 314);
  447. AssignVerCapacity(21 ,TErrorCorrectionLevel.High, 969, 587, 403, 248);
  448. AssignVerCapacity(22 ,TErrorCorrectionLevel.Low ,2409 ,1460 ,1003 ,618);
  449. AssignVerCapacity(22 ,TErrorCorrectionLevel.Medium, 1872 , 1134 , 779, 480);
  450. AssignVerCapacity(22 ,TErrorCorrectionLevel.Quartile, 1358 , 823, 565, 348);
  451. AssignVerCapacity(22 ,TErrorCorrectionLevel.High, 1056 , 640, 439, 270);
  452. AssignVerCapacity(23 ,TErrorCorrectionLevel.Low ,2620 ,1588 ,1091 ,672);
  453. AssignVerCapacity(23 ,TErrorCorrectionLevel.Medium, 2059 , 1248 , 857, 528);
  454. AssignVerCapacity(23 ,TErrorCorrectionLevel.Quartile, 1468 , 890, 611, 376);
  455. AssignVerCapacity(23 ,TErrorCorrectionLevel.High, 1108 , 672, 461, 284);
  456. AssignVerCapacity(24 ,TErrorCorrectionLevel.Low ,2812 ,1704 ,1171 ,721);
  457. AssignVerCapacity(24 ,TErrorCorrectionLevel.Medium, 2188 , 1326 , 911, 561);
  458. AssignVerCapacity(24 ,TErrorCorrectionLevel.Quartile, 1588 , 963, 661, 407);
  459. AssignVerCapacity(24 ,TErrorCorrectionLevel.High, 1228 , 744, 511, 315);
  460. AssignVerCapacity(25 ,TErrorCorrectionLevel.Low ,3057 ,1853 ,1273 ,784);
  461. AssignVerCapacity(25 ,TErrorCorrectionLevel.Medium, 2395 , 1451 , 997, 614);
  462. AssignVerCapacity(25 ,TErrorCorrectionLevel.Quartile, 1718 , 1041 , 715, 440);
  463. AssignVerCapacity(25 ,TErrorCorrectionLevel.High, 1286 , 779, 535, 330);
  464. AssignVerCapacity(26 ,TErrorCorrectionLevel.Low ,3283 ,1990 ,1367 ,842);
  465. AssignVerCapacity(26 ,TErrorCorrectionLevel.Medium, 2544 , 1542 , 1059 , 652);
  466. AssignVerCapacity(26 ,TErrorCorrectionLevel.Quartile, 1804 , 1094 , 751, 462);
  467. AssignVerCapacity(26 ,TErrorCorrectionLevel.High, 1425 , 864, 593, 365);
  468. AssignVerCapacity(27 ,TErrorCorrectionLevel.Low ,3517 ,2132 ,1465 ,902);
  469. AssignVerCapacity(27 ,TErrorCorrectionLevel.Medium, 2701 , 1637 , 1125 , 692);
  470. AssignVerCapacity(27 ,TErrorCorrectionLevel.Quartile, 1933 , 1172 , 805, 496);
  471. AssignVerCapacity(27 ,TErrorCorrectionLevel.High, 1501 , 910, 625, 385);
  472. AssignVerCapacity(28 ,TErrorCorrectionLevel.Low ,3669 ,2223 ,1528 ,940);
  473. AssignVerCapacity(28 ,TErrorCorrectionLevel.Medium, 2857 , 1732 , 1190 , 732);
  474. AssignVerCapacity(28 ,TErrorCorrectionLevel.Quartile, 2085 , 1263 , 868, 534);
  475. AssignVerCapacity(28 ,TErrorCorrectionLevel.High, 1581 , 958, 658, 405);
  476. AssignVerCapacity(29 ,TErrorCorrectionLevel.Low ,3909 ,2369 ,1628 ,1002);
  477. AssignVerCapacity(29 ,TErrorCorrectionLevel.Medium, 3035 , 1839 , 1264 , 778);
  478. AssignVerCapacity(29 ,TErrorCorrectionLevel.Quartile, 2181 , 1322 , 908, 559);
  479. AssignVerCapacity(29 ,TErrorCorrectionLevel.High, 1677 , 1016 , 698, 430);
  480. AssignVerCapacity(30 ,TErrorCorrectionLevel.Low ,4158 ,2520 ,1732 ,1066);
  481. AssignVerCapacity(30 ,TErrorCorrectionLevel.Medium, 3289 , 1994 , 1370 , 843);
  482. AssignVerCapacity(30 ,TErrorCorrectionLevel.Quartile, 2358 , 1429 , 982, 604);
  483. AssignVerCapacity(30 ,TErrorCorrectionLevel.High, 1782 , 1080 , 742, 457);
  484. AssignVerCapacity(31 ,TErrorCorrectionLevel.Low ,4417 ,2677 ,1840 ,1132);
  485. AssignVerCapacity(31 ,TErrorCorrectionLevel.Medium, 3486 , 2113 , 1452 , 894);
  486. AssignVerCapacity(31 ,TErrorCorrectionLevel.Quartile, 2473 , 1499 , 1030 , 634);
  487. AssignVerCapacity(31 ,TErrorCorrectionLevel.High, 1897 , 1150 , 790, 486);
  488. AssignVerCapacity(32 ,TErrorCorrectionLevel.Low ,4686 ,2840 ,1952 ,1201);
  489. AssignVerCapacity(32 ,TErrorCorrectionLevel.Medium, 3693 , 2238 , 1538 , 947);
  490. AssignVerCapacity(32 ,TErrorCorrectionLevel.Quartile, 2670 , 1618 , 1112 , 684);
  491. AssignVerCapacity(32 ,TErrorCorrectionLevel.High, 2022 , 1226 , 842, 518);
  492. AssignVerCapacity(33 ,TErrorCorrectionLevel.Low ,4965 ,3009 ,2068 ,1273);
  493. AssignVerCapacity(33 ,TErrorCorrectionLevel.Medium, 3909 , 2369 , 1628 , 1002);
  494. AssignVerCapacity(33 ,TErrorCorrectionLevel.Quartile, 2805 , 1700 , 1168 , 719);
  495. AssignVerCapacity(33 ,TErrorCorrectionLevel.High, 2157 , 1307 , 898, 553);
  496. AssignVerCapacity(34 ,TErrorCorrectionLevel.Low ,5253 ,3183 ,2188 ,1347);
  497. AssignVerCapacity(34 ,TErrorCorrectionLevel.Medium, 4134 , 2506 , 1722 , 1060);
  498. AssignVerCapacity(34 ,TErrorCorrectionLevel.Quartile, 2949 , 1787 , 1228 , 756);
  499. AssignVerCapacity(34 ,TErrorCorrectionLevel.High, 2301 , 1394 , 958, 590);
  500. AssignVerCapacity(35 ,TErrorCorrectionLevel.Low ,5529 ,3351 ,2303 ,1417);
  501. AssignVerCapacity(35 ,TErrorCorrectionLevel.Medium, 4343 , 2632 , 1809 , 1113);
  502. AssignVerCapacity(35 ,TErrorCorrectionLevel.Quartile, 3081 , 1867 , 1283 , 790);
  503. AssignVerCapacity(35 ,TErrorCorrectionLevel.High, 2361 , 1431 , 983, 605);
  504. AssignVerCapacity(36 ,TErrorCorrectionLevel.Low ,5836 ,3537 ,2431 ,1496);
  505. AssignVerCapacity(36 ,TErrorCorrectionLevel.Medium, 4588 , 2780 , 1911 , 1176);
  506. AssignVerCapacity(36 ,TErrorCorrectionLevel.Quartile, 3244 , 1966 , 1351 , 832);
  507. AssignVerCapacity(36 ,TErrorCorrectionLevel.High, 2524 , 1530 , 1051 , 647);
  508. AssignVerCapacity(37 ,TErrorCorrectionLevel.Low ,6153 ,3729 ,2563 ,1577);
  509. AssignVerCapacity(37 ,TErrorCorrectionLevel.Medium, 4775 , 2894 , 1989 , 1224);
  510. AssignVerCapacity(37 ,TErrorCorrectionLevel.Quartile, 3417 , 2071 , 1423 , 876);
  511. AssignVerCapacity(37 ,TErrorCorrectionLevel.High, 2625 , 1591 , 1093 , 673);
  512. AssignVerCapacity(38 ,TErrorCorrectionLevel.Low ,6479 ,3927 ,2699 ,1661);
  513. AssignVerCapacity(38 ,TErrorCorrectionLevel.Medium, 5039 , 3054 , 2099 , 1292);
  514. AssignVerCapacity(38 ,TErrorCorrectionLevel.Quartile, 3599 , 2181 , 1499 , 923);
  515. AssignVerCapacity(38 ,TErrorCorrectionLevel.High, 2735 , 1658 , 1139 , 701);
  516. AssignVerCapacity(39 ,TErrorCorrectionLevel.Low ,6743 ,4087 ,2809 ,1729);
  517. AssignVerCapacity(39 ,TErrorCorrectionLevel.Medium, 5313 , 3220 , 2213 , 1362);
  518. AssignVerCapacity(39 ,TErrorCorrectionLevel.Quartile, 3791 , 2298 , 1579 , 972);
  519. AssignVerCapacity(39 ,TErrorCorrectionLevel.High, 2927 , 1774 , 1219 , 750);
  520. AssignVerCapacity(40 ,TErrorCorrectionLevel.Low ,7089 ,4296 ,2953 ,1817);
  521. AssignVerCapacity(40 ,TErrorCorrectionLevel.Medium, 5596 , 3391 , 2331 , 1435);
  522. AssignVerCapacity(40 ,TErrorCorrectionLevel.Quartile, 3993 , 2420 , 1663 , 1024);
  523. AssignVerCapacity(40 ,TErrorCorrectionLevel.High, 3057 , 1852 , 1273 , 784);
  524. AssignCodeWords(1, TErrorCorrectionLevel.Low, 19 ,7 ,1 ,19 );
  525. AssignCodeWords(1, TErrorCorrectionLevel.Medium, 16 ,10 ,1 ,16 );
  526. AssignCodeWords(1, TErrorCorrectionLevel.Quartile, 13 ,13 ,1 ,13 );
  527. AssignCodeWords(1, TErrorCorrectionLevel.High, 9 ,17 ,1 ,9 );
  528. AssignCodeWords(2, TErrorCorrectionLevel.Low, 34 ,10 ,1 ,34 );
  529. AssignCodeWords(2, TErrorCorrectionLevel.Medium, 28 ,16 ,1 ,28 );
  530. AssignCodeWords(2, TErrorCorrectionLevel.Quartile, 22 ,22 ,1 ,22 );
  531. AssignCodeWords(2, TErrorCorrectionLevel.High, 16 ,28 ,1 ,16 );
  532. AssignCodeWords(3, TErrorCorrectionLevel.Low, 55 ,15 ,1 ,55 );
  533. AssignCodeWords(3, TErrorCorrectionLevel.Medium, 44 ,26 ,1 ,44 );
  534. AssignCodeWords(3, TErrorCorrectionLevel.Quartile, 34 ,18 ,2 ,17 );
  535. AssignCodeWords(3, TErrorCorrectionLevel.High, 26 ,22 ,2 ,13 );
  536. AssignCodeWords(4, TErrorCorrectionLevel.Low, 80 ,20 ,1 ,80 );
  537. AssignCodeWords(4, TErrorCorrectionLevel.Medium, 64 ,18 ,2 ,32 );
  538. AssignCodeWords(4, TErrorCorrectionLevel.Quartile, 48 ,26 ,2 ,24 );
  539. AssignCodeWords(4, TErrorCorrectionLevel.High, 36 ,16 ,4 ,9 );
  540. AssignCodeWords(5, TErrorCorrectionLevel.Low, 108 ,26 ,1 ,108 );
  541. AssignCodeWords(5, TErrorCorrectionLevel.Medium, 86 ,24 ,2 ,43 );
  542. AssignCodeWords(5, TErrorCorrectionLevel.Quartile, 62 ,18 ,2 ,15 ,2 ,16 );
  543. AssignCodeWords(5, TErrorCorrectionLevel.High, 46 ,22 ,2 ,11 ,2 ,12 );
  544. AssignCodeWords(6, TErrorCorrectionLevel.Low, 136 ,18 ,2 ,68 );
  545. AssignCodeWords(6, TErrorCorrectionLevel.Medium, 108 ,16 ,4 ,27 );
  546. AssignCodeWords(6, TErrorCorrectionLevel.Quartile, 76 ,24 ,4 ,19 );
  547. AssignCodeWords(6, TErrorCorrectionLevel.High, 60 ,28 ,4 ,15 );
  548. AssignCodeWords(7, TErrorCorrectionLevel.Low, 156 ,20 ,2 ,78 );
  549. AssignCodeWords(7, TErrorCorrectionLevel.Medium, 124 ,18 ,4 ,31 );
  550. AssignCodeWords(7, TErrorCorrectionLevel.Quartile, 88 ,18 ,2 ,14 ,4 ,15 );
  551. AssignCodeWords(7, TErrorCorrectionLevel.High, 66 ,26 ,4 ,13 ,1 ,14 );
  552. AssignCodeWords(8, TErrorCorrectionLevel.Low, 194 ,24 ,2 ,97 );
  553. AssignCodeWords(8, TErrorCorrectionLevel.Medium, 154 ,22 ,2 ,38 ,2 ,39 );
  554. AssignCodeWords(8, TErrorCorrectionLevel.Quartile, 110 ,22 ,4 ,18 ,2 ,19 );
  555. AssignCodeWords(8, TErrorCorrectionLevel.High, 86 ,26 ,4 ,14 ,2 ,15 );
  556. AssignCodeWords(9, TErrorCorrectionLevel.Low, 232 ,30 ,2 ,116 );
  557. AssignCodeWords(9, TErrorCorrectionLevel.Medium, 182 ,22 ,3 ,36 ,2 ,37 );
  558. AssignCodeWords(9, TErrorCorrectionLevel.Quartile, 132 ,20 ,4 ,16 ,4 ,17 );
  559. AssignCodeWords(9, TErrorCorrectionLevel.High, 100 ,24 ,4 ,12 ,4 ,13 );
  560. AssignCodeWords(10, TErrorCorrectionLevel.Low, 274 ,18 ,2 ,68 ,2 ,69 );
  561. AssignCodeWords(10, TErrorCorrectionLevel.Medium, 216 ,26 ,4 ,43 ,1 ,44 );
  562. AssignCodeWords(10, TErrorCorrectionLevel.Quartile, 154 ,24 ,6 ,19 ,2 ,20 );
  563. AssignCodeWords(10, TErrorCorrectionLevel.High, 122 ,28 ,6 ,15 ,2 ,16 );
  564. AssignCodeWords(11, TErrorCorrectionLevel.Low, 324 ,20 ,4 ,81 );
  565. AssignCodeWords(11, TErrorCorrectionLevel.Medium, 254 ,30 ,1 ,50 ,4 ,51 );
  566. AssignCodeWords(11, TErrorCorrectionLevel.Quartile, 180 ,28 ,4 ,22 ,4 ,23 );
  567. AssignCodeWords(11, TErrorCorrectionLevel.High, 140 ,24 ,3 ,12 ,8 ,13 );
  568. AssignCodeWords(12, TErrorCorrectionLevel.Low, 370 ,24 ,2 ,92 ,2 ,93 );
  569. AssignCodeWords(12, TErrorCorrectionLevel.Medium, 290 ,22 ,6 ,36 ,2 ,37 );
  570. AssignCodeWords(12, TErrorCorrectionLevel.Quartile, 206 ,26 ,4 ,20 ,6 ,21 );
  571. AssignCodeWords(12, TErrorCorrectionLevel.High, 158 ,28 ,7 ,14 ,4 ,15 );
  572. AssignCodeWords(13, TErrorCorrectionLevel.Low, 428 ,26 ,4 ,107);
  573. AssignCodeWords(13, TErrorCorrectionLevel.Medium, 334 ,22 ,8 ,37 ,1 ,38 );
  574. AssignCodeWords(13, TErrorCorrectionLevel.Quartile, 244 ,24 ,8 ,20 ,4 ,21 );
  575. AssignCodeWords(13, TErrorCorrectionLevel.High, 180 ,22 ,12 ,11 ,4 ,12 );
  576. AssignCodeWords(14, TErrorCorrectionLevel.Low, 461 ,30 ,3 ,115 ,1 ,116 );
  577. AssignCodeWords(14, TErrorCorrectionLevel.Medium, 365 ,24 ,4 ,40 ,5 ,41 );
  578. AssignCodeWords(14, TErrorCorrectionLevel.Quartile, 261 ,20 ,11 ,16 ,5 ,17 );
  579. AssignCodeWords(14, TErrorCorrectionLevel.High, 197 ,24 ,11 ,12 ,5 ,13 );
  580. AssignCodeWords(15, TErrorCorrectionLevel.Low, 523 ,22 ,5 ,87 ,1 ,88 );
  581. AssignCodeWords(15, TErrorCorrectionLevel.Medium, 415 ,24 ,5 ,41 ,5 ,42 );
  582. AssignCodeWords(15, TErrorCorrectionLevel.Quartile, 295 ,30 ,5 ,24 ,7 ,25 );
  583. AssignCodeWords(15, TErrorCorrectionLevel.High, 223 ,24 ,11 ,12 ,7 ,13 );
  584. AssignCodeWords(16, TErrorCorrectionLevel.Low, 589 ,24 ,5 ,98 ,1 ,99 );
  585. AssignCodeWords(16, TErrorCorrectionLevel.Medium, 453 ,28 ,7 ,45 ,3 ,46 );
  586. AssignCodeWords(16, TErrorCorrectionLevel.Quartile, 325 ,24 ,15 ,19 ,2 ,20 );
  587. AssignCodeWords(16, TErrorCorrectionLevel.High, 253 ,30 ,3 ,15 ,13 ,16 );
  588. AssignCodeWords(17, TErrorCorrectionLevel.Low, 647 ,28 ,1 ,107 ,5 ,108 );
  589. AssignCodeWords(17, TErrorCorrectionLevel.Medium, 507 ,28 ,10 ,46 ,1 ,47 );
  590. AssignCodeWords(17, TErrorCorrectionLevel.Quartile, 367 ,28 ,1 ,22 ,15 ,23 );
  591. AssignCodeWords(17, TErrorCorrectionLevel.High, 283 ,28 ,2 ,14 ,17 ,15 );
  592. AssignCodeWords(18, TErrorCorrectionLevel.Low, 721 ,30 ,5 ,120 ,1 ,121 );
  593. AssignCodeWords(18, TErrorCorrectionLevel.Medium, 563 ,26 ,9 ,43 ,4 ,44 );
  594. AssignCodeWords(18, TErrorCorrectionLevel.Quartile, 397 ,28 ,17 ,22 ,1 ,23 );
  595. AssignCodeWords(18, TErrorCorrectionLevel.High, 313 ,28 ,2 ,14 ,19 ,15 );
  596. AssignCodeWords(19, TErrorCorrectionLevel.Low, 795 ,28 ,3 ,113 ,4 ,114 );
  597. AssignCodeWords(19, TErrorCorrectionLevel.Medium, 627 ,26 ,3 ,44 ,11 ,45 );
  598. AssignCodeWords(19, TErrorCorrectionLevel.Quartile, 445 ,26 ,17 ,21 ,4 ,22 );
  599. AssignCodeWords(19, TErrorCorrectionLevel.High, 341 ,26 ,9 ,13 ,16 ,14 );
  600. AssignCodeWords(20, TErrorCorrectionLevel.Low, 861 ,28 ,3 ,107 ,5 ,108 );
  601. AssignCodeWords(20, TErrorCorrectionLevel.Medium, 669 ,26 ,3 ,41 ,13 ,42 );
  602. AssignCodeWords(20, TErrorCorrectionLevel.Quartile, 485 ,30 ,15 ,24 ,5 ,25 );
  603. AssignCodeWords(20, TErrorCorrectionLevel.High, 385 ,28 ,15 ,15 ,10 ,16 );
  604. AssignCodeWords(21, TErrorCorrectionLevel.Low, 932 ,28 ,4 ,116 ,4 ,117 );
  605. AssignCodeWords(21, TErrorCorrectionLevel.Medium, 714 ,26 ,17 ,42 );
  606. AssignCodeWords(21, TErrorCorrectionLevel.Quartile, 512 ,28 ,17 ,22 ,6 ,23 );
  607. AssignCodeWords(21, TErrorCorrectionLevel.High, 406 ,30 ,19 ,16 ,6 ,17 );
  608. AssignCodeWords(22, TErrorCorrectionLevel.Low, 1006 ,28 ,2 ,111 ,7 ,112 );
  609. AssignCodeWords(22, TErrorCorrectionLevel.Medium, 782 ,28 ,17 ,46 );
  610. AssignCodeWords(22, TErrorCorrectionLevel.Quartile, 568 ,30 ,7 ,24 ,16 ,25 );
  611. AssignCodeWords(22, TErrorCorrectionLevel.High, 442 ,24 ,34 ,13 );
  612. AssignCodeWords(23, TErrorCorrectionLevel.Low, 1094 ,30 ,4 ,121 ,5 ,122 );
  613. AssignCodeWords(23, TErrorCorrectionLevel.Medium, 860 ,28 ,4 ,47 ,14 ,48 );
  614. AssignCodeWords(23, TErrorCorrectionLevel.Quartile, 614 ,30 ,11 ,24 ,14 ,25 );
  615. AssignCodeWords(23, TErrorCorrectionLevel.High, 464 ,30 ,16 ,15 ,14 ,16 );
  616. AssignCodeWords(24, TErrorCorrectionLevel.Low, 1174 ,30 ,6 ,117 ,4 ,118 );
  617. AssignCodeWords(24, TErrorCorrectionLevel.Medium, 914 ,28 ,6 ,45 ,14 ,46 );
  618. AssignCodeWords(24, TErrorCorrectionLevel.Quartile, 664 ,30 ,11 ,24 ,16 ,25 );
  619. AssignCodeWords(24, TErrorCorrectionLevel.High, 514 ,30 ,30 ,16 ,2 ,17 );
  620. AssignCodeWords(25, TErrorCorrectionLevel.Low, 1276 ,26 ,8 ,106 ,4 ,107 );
  621. AssignCodeWords(25, TErrorCorrectionLevel.Medium, 1000 ,28 ,8 ,47 ,13 ,48 );
  622. AssignCodeWords(25, TErrorCorrectionLevel.Quartile, 718 ,30 ,7 ,24 ,22 ,25 );
  623. AssignCodeWords(25, TErrorCorrectionLevel.High, 538 ,30 ,22 ,15 ,13 ,16 );
  624. AssignCodeWords(26, TErrorCorrectionLevel.Low, 1370 ,28 ,10 ,114 ,2 ,115 );
  625. AssignCodeWords(26, TErrorCorrectionLevel.Medium, 1062 ,28 ,19 ,46 ,4 ,47 );
  626. AssignCodeWords(26, TErrorCorrectionLevel.Quartile, 754 ,28 ,28 ,22 ,6 ,23 );
  627. AssignCodeWords(26, TErrorCorrectionLevel.High, 596 ,30 ,33 ,16 ,4 ,17 );
  628. AssignCodeWords(27, TErrorCorrectionLevel.Low, 1468 ,30 ,8 ,122 ,4 ,123 );
  629. AssignCodeWords(27, TErrorCorrectionLevel.Medium, 1128 ,28 ,22 ,45 ,3 ,46 );
  630. AssignCodeWords(27, TErrorCorrectionLevel.Quartile, 808 ,30 ,8 ,23 ,26 ,24 );
  631. AssignCodeWords(27, TErrorCorrectionLevel.High, 628 ,30 ,12 ,15 ,28 ,16 );
  632. AssignCodeWords(28, TErrorCorrectionLevel.Low, 1531 ,30 ,3 ,117 ,10 ,118 );
  633. AssignCodeWords(28, TErrorCorrectionLevel.Medium, 1193 ,28 ,3 ,45 ,23 ,46 );
  634. AssignCodeWords(28, TErrorCorrectionLevel.Quartile, 871 ,30 ,4 ,24 ,31 ,25 );
  635. AssignCodeWords(28, TErrorCorrectionLevel.High, 661 ,30 ,11 ,15 ,31 ,16 );
  636. AssignCodeWords(29, TErrorCorrectionLevel.Low, 1631 ,30 ,7 ,116 ,7 ,117 );
  637. AssignCodeWords(29, TErrorCorrectionLevel.Medium, 1267 ,28 ,21 ,45 ,7 ,46 );
  638. AssignCodeWords(29, TErrorCorrectionLevel.Quartile, 911 ,30 ,1 ,23 ,37 ,24 );
  639. AssignCodeWords(29, TErrorCorrectionLevel.High, 701 ,30 ,19 ,15 ,26 ,16 );
  640. AssignCodeWords(30, TErrorCorrectionLevel.Low, 1735 ,30 ,5 ,115 ,10 ,116 );
  641. AssignCodeWords(30, TErrorCorrectionLevel.Medium, 1373 ,28 ,19 ,47 ,10 ,48 );
  642. AssignCodeWords(30, TErrorCorrectionLevel.Quartile, 985 ,30 ,15 ,24 ,25 ,25 );
  643. AssignCodeWords(30, TErrorCorrectionLevel.High, 745 ,30 ,23 ,15 ,25 ,16 );
  644. AssignCodeWords(31, TErrorCorrectionLevel.Low, 1843 ,30 ,13 ,115 ,3 ,116 );
  645. AssignCodeWords(31, TErrorCorrectionLevel.Medium, 1455 ,28 ,2 ,46 ,29 ,47 );
  646. AssignCodeWords(31, TErrorCorrectionLevel.Quartile, 1033 ,30 ,42 ,24 ,1 ,25 );
  647. AssignCodeWords(31, TErrorCorrectionLevel.High, 793 ,30 ,23 ,15 ,28 ,16 );
  648. AssignCodeWords(32, TErrorCorrectionLevel.Low, 1955, 30, 17 , 115);
  649. AssignCodeWords(32, TErrorCorrectionLevel.Medium, 1541 ,28 ,10 ,46 ,23 ,47 );
  650. AssignCodeWords(32, TErrorCorrectionLevel.Quartile, 1115 ,30 ,10 ,24 ,35 ,25 );
  651. AssignCodeWords(32, TErrorCorrectionLevel.High, 845 ,30 ,19 ,15 ,35 ,16 );
  652. AssignCodeWords(33, TErrorCorrectionLevel.Low, 2071 ,30 ,17 ,115 ,1 ,116 );
  653. AssignCodeWords(33, TErrorCorrectionLevel.Medium, 1631 ,28 ,14 ,46 ,21 ,47 );
  654. AssignCodeWords(33, TErrorCorrectionLevel.Quartile, 1171 ,30 ,29 ,24 ,19 ,25 );
  655. AssignCodeWords(33, TErrorCorrectionLevel.High, 901 ,30 ,11 ,15 ,46 ,16 );
  656. AssignCodeWords(34, TErrorCorrectionLevel.Low, 2191 ,30 ,13 ,115 ,6 ,116 );
  657. AssignCodeWords(34, TErrorCorrectionLevel.Medium, 1725 ,28 ,14 ,46 ,23 ,47 );
  658. AssignCodeWords(34, TErrorCorrectionLevel.Quartile, 1231 ,30 ,44 ,24 ,7 ,25 );
  659. AssignCodeWords(34, TErrorCorrectionLevel.High, 961 ,30 ,59 ,16 ,1 ,17 );
  660. AssignCodeWords(35, TErrorCorrectionLevel.Low, 2306 ,30 ,12 ,121 ,7 ,122 );
  661. AssignCodeWords(35, TErrorCorrectionLevel.Medium, 1812 ,28 ,12 ,47 ,26 ,48 );
  662. AssignCodeWords(35, TErrorCorrectionLevel.Quartile, 1286 ,30 ,39 ,24 ,14 ,25 );
  663. AssignCodeWords(35, TErrorCorrectionLevel.High, 986 ,30 ,22 ,15 ,41 ,16 );
  664. AssignCodeWords(36, TErrorCorrectionLevel.Low, 2434 ,30 ,6 ,121 ,14 ,122 );
  665. AssignCodeWords(36, TErrorCorrectionLevel.Medium, 1914 ,28 ,6 ,47 ,34 ,48 );
  666. AssignCodeWords(36, TErrorCorrectionLevel.Quartile, 1354 ,30 ,46 ,24 ,10 ,25 );
  667. AssignCodeWords(36, TErrorCorrectionLevel.High, 1054 ,30 ,2 ,15 ,64 ,16 );
  668. AssignCodeWords(37, TErrorCorrectionLevel.Low, 2566 ,30 ,17 ,122 ,4 ,123 );
  669. AssignCodeWords(37, TErrorCorrectionLevel.Medium, 1992 ,28 ,29 ,46 ,14 ,47 );
  670. AssignCodeWords(37, TErrorCorrectionLevel.Quartile, 1426 ,30 ,49 ,24 ,10 ,25 );
  671. AssignCodeWords(37, TErrorCorrectionLevel.High, 1096 ,30 ,24 ,15 ,46 ,16 );
  672. AssignCodeWords(38, TErrorCorrectionLevel.Low, 2702 ,30 ,4 ,122 ,18 ,123 );
  673. AssignCodeWords(38, TErrorCorrectionLevel.Medium, 2102 ,28 ,13 ,46 ,32 ,47 );
  674. AssignCodeWords(38, TErrorCorrectionLevel.Quartile, 1502 ,30 ,48 ,24 ,14 ,25 );
  675. AssignCodeWords(38, TErrorCorrectionLevel.High, 1142 ,30 ,42 ,15 ,32 ,16 );
  676. AssignCodeWords(39, TErrorCorrectionLevel.Low, 2812 ,30 ,20 ,117 ,4 ,118 );
  677. AssignCodeWords(39, TErrorCorrectionLevel.Medium, 2216 ,28 ,40 ,47 ,7 ,48 );
  678. AssignCodeWords(39, TErrorCorrectionLevel.Quartile, 1582 ,30 ,43 ,24 ,22 ,25 );
  679. AssignCodeWords(39, TErrorCorrectionLevel.High, 1222 ,30 ,10 ,15 ,67 ,16 );
  680. AssignCodeWords(40, TErrorCorrectionLevel.Low, 2956 ,30 ,19 ,118 ,6 ,119 );
  681. AssignCodeWords(40, TErrorCorrectionLevel.Medium, 2334 ,28 ,18 ,47 ,31 ,48 );
  682. AssignCodeWords(40, TErrorCorrectionLevel.Quartile, 1666 ,30 ,34 ,24 ,34 ,25 );
  683. AssignCodeWords(40, TErrorCorrectionLevel.High, 1276 ,30 ,20 ,15 ,61 ,16 );
  684. end;
  685. constructor TQRCode.Create;
  686. var
  687. i: Integer;
  688. begin
  689. inherited Create;
  690. FUpdateDepth := 0;
  691. FReservedAreas := TList<TRect>.Create;
  692. SetLength(FPenaltyScores,8);
  693. for i := 0 to 7 do
  694. SetLength(FPenaltyScores[i],4);
  695. FMaskInUse := TMask.m0;
  696. FMask := TMask.Auto;
  697. FVersion := TVersion.Auto;
  698. FVersionInUse := TVersion.v1;
  699. FMode := TQRMode.Numeric;
  700. FECL := TErrorCorrectionLevel.Auto;
  701. FECLInUse := TErrorCorrectionLevel.Low;
  702. SetLength(FData,0);
  703. SetLength(FCodeWords, 0);
  704. FBitsLen := 0;
  705. FBitsPos := 0;
  706. SetLength(FBits,0);
  707. SetLength(FModules,0);
  708. FDataBits := '';
  709. FOnPaint := nil;
  710. SetLength(FLogTable, 256);
  711. FLogTable[0] := 1;
  712. FLogTable[1] := 2;
  713. FLogTable[2] := 4;
  714. FLogTable[3] := 8;
  715. FLogTable[4] := 16;
  716. FLogTable[5] := 32;
  717. FLogTable[6] := 64;
  718. FLogTable[7] := 128;
  719. FLogTable[8] := 29;
  720. FLogTable[9] := 58;
  721. FLogTable[10] := 116;
  722. FLogTable[11] := 232;
  723. FLogTable[12] := 205;
  724. FLogTable[13] := 135;
  725. FLogTable[14] := 19;
  726. FLogTable[15] := 38;
  727. FLogTable[16] := 76;
  728. FLogTable[17] := 152;
  729. FLogTable[18] := 45;
  730. FLogTable[19] := 90;
  731. FLogTable[20] := 180;
  732. FLogTable[21] := 117;
  733. FLogTable[22] := 234;
  734. FLogTable[23] := 201;
  735. FLogTable[24] := 143;
  736. FLogTable[25] := 3;
  737. FLogTable[26] := 6;
  738. FLogTable[27] := 12;
  739. FLogTable[28] := 24;
  740. FLogTable[29] := 48;
  741. FLogTable[30] := 96;
  742. FLogTable[31] := 192;
  743. FLogTable[32] := 157;
  744. FLogTable[33] := 39;
  745. FLogTable[34] := 78;
  746. FLogTable[35] := 156;
  747. FLogTable[36] := 37;
  748. FLogTable[37] := 74;
  749. FLogTable[38] := 148;
  750. FLogTable[39] := 53;
  751. FLogTable[40] := 106;
  752. FLogTable[41] := 212;
  753. FLogTable[42] := 181;
  754. FLogTable[43] := 119;
  755. FLogTable[44] := 238;
  756. FLogTable[45] := 193;
  757. FLogTable[46] := 159;
  758. FLogTable[47] := 35;
  759. FLogTable[48] := 70;
  760. FLogTable[49] := 140;
  761. FLogTable[50] := 5;
  762. FLogTable[51] := 10;
  763. FLogTable[52] := 20;
  764. FLogTable[53] := 40;
  765. FLogTable[54] := 80;
  766. FLogTable[55] := 160;
  767. FLogTable[56] := 93;
  768. FLogTable[57] := 186;
  769. FLogTable[58] := 105;
  770. FLogTable[59] := 210;
  771. FLogTable[60] := 185;
  772. FLogTable[61] := 111;
  773. FLogTable[62] := 222;
  774. FLogTable[63] := 161;
  775. FLogTable[64] := 95;
  776. FLogTable[65] := 190;
  777. FLogTable[66] := 97;
  778. FLogTable[67] := 194;
  779. FLogTable[68] := 153;
  780. FLogTable[69] := 47;
  781. FLogTable[70] := 94;
  782. FLogTable[71] := 188;
  783. FLogTable[72] := 101;
  784. FLogTable[73] := 202;
  785. FLogTable[74] := 137;
  786. FLogTable[75] := 15;
  787. FLogTable[76] := 30;
  788. FLogTable[77] := 60;
  789. FLogTable[78] := 120;
  790. FLogTable[79] := 240;
  791. FLogTable[80] := 253;
  792. FLogTable[81] := 231;
  793. FLogTable[82] := 211;
  794. FLogTable[83] := 187;
  795. FLogTable[84] := 107;
  796. FLogTable[85] := 214;
  797. FLogTable[86] := 177;
  798. FLogTable[87] := 127;
  799. FLogTable[88] := 254;
  800. FLogTable[89] := 225;
  801. FLogTable[90] := 223;
  802. FLogTable[91] := 163;
  803. FLogTable[92] := 91;
  804. FLogTable[93] := 182;
  805. FLogTable[94] := 113;
  806. FLogTable[95] := 226;
  807. FLogTable[96] := 217;
  808. FLogTable[97] := 175;
  809. FLogTable[98] := 67;
  810. FLogTable[99] := 134;
  811. FLogTable[100] := 17;
  812. FLogTable[101] := 34;
  813. FLogTable[102] := 68;
  814. FLogTable[103] := 136;
  815. FLogTable[104] := 13;
  816. FLogTable[105] := 26;
  817. FLogTable[106] := 52;
  818. FLogTable[107] := 104;
  819. FLogTable[108] := 208;
  820. FLogTable[109] := 189;
  821. FLogTable[110] := 103;
  822. FLogTable[111] := 206;
  823. FLogTable[112] := 129;
  824. FLogTable[113] := 31;
  825. FLogTable[114] := 62;
  826. FLogTable[115] := 124;
  827. FLogTable[116] := 248;
  828. FLogTable[117] := 237;
  829. FLogTable[118] := 199;
  830. FLogTable[119] := 147;
  831. FLogTable[120] := 59;
  832. FLogTable[121] := 118;
  833. FLogTable[122] := 236;
  834. FLogTable[123] := 197;
  835. FLogTable[124] := 151;
  836. FLogTable[125] := 51;
  837. FLogTable[126] := 102;
  838. FLogTable[127] := 204;
  839. FLogTable[128] := 133;
  840. FLogTable[129] := 23;
  841. FLogTable[130] := 46;
  842. FLogTable[131] := 92;
  843. FLogTable[132] := 184;
  844. FLogTable[133] := 109;
  845. FLogTable[134] := 218;
  846. FLogTable[135] := 169;
  847. FLogTable[136] := 79;
  848. FLogTable[137] := 158;
  849. FLogTable[138] := 33;
  850. FLogTable[139] := 66;
  851. FLogTable[140] := 132;
  852. FLogTable[141] := 21;
  853. FLogTable[142] := 42;
  854. FLogTable[143] := 84;
  855. FLogTable[144] := 168;
  856. FLogTable[145] := 77;
  857. FLogTable[146] := 154;
  858. FLogTable[147] := 41;
  859. FLogTable[148] := 82;
  860. FLogTable[149] := 164;
  861. FLogTable[150] := 85;
  862. FLogTable[151] := 170;
  863. FLogTable[152] := 73;
  864. FLogTable[153] := 146;
  865. FLogTable[154] := 57;
  866. FLogTable[155] := 114;
  867. FLogTable[156] := 228;
  868. FLogTable[157] := 213;
  869. FLogTable[158] := 183;
  870. FLogTable[159] := 115;
  871. FLogTable[160] := 230;
  872. FLogTable[161] := 209;
  873. FLogTable[162] := 191;
  874. FLogTable[163] := 99;
  875. FLogTable[164] := 198;
  876. FLogTable[165] := 145;
  877. FLogTable[166] := 63;
  878. FLogTable[167] := 126;
  879. FLogTable[168] := 252;
  880. FLogTable[169] := 229;
  881. FLogTable[170] := 215;
  882. FLogTable[171] := 179;
  883. FLogTable[172] := 123;
  884. FLogTable[173] := 246;
  885. FLogTable[174] := 241;
  886. FLogTable[175] := 255;
  887. FLogTable[176] := 227;
  888. FLogTable[177] := 219;
  889. FLogTable[178] := 171;
  890. FLogTable[179] := 75;
  891. FLogTable[180] := 150;
  892. FLogTable[181] := 49;
  893. FLogTable[182] := 98;
  894. FLogTable[183] := 196;
  895. FLogTable[184] := 149;
  896. FLogTable[185] := 55;
  897. FLogTable[186] := 110;
  898. FLogTable[187] := 220;
  899. FLogTable[188] := 165;
  900. FLogTable[189] := 87;
  901. FLogTable[190] := 174;
  902. FLogTable[191] := 65;
  903. FLogTable[192] := 130;
  904. FLogTable[193] := 25;
  905. FLogTable[194] := 50;
  906. FLogTable[195] := 100;
  907. FLogTable[196] := 200;
  908. FLogTable[197] := 141;
  909. FLogTable[198] := 7;
  910. FLogTable[199] := 14;
  911. FLogTable[200] := 28;
  912. FLogTable[201] := 56;
  913. FLogTable[202] := 112;
  914. FLogTable[203] := 224;
  915. FLogTable[204] := 221;
  916. FLogTable[205] := 167;
  917. FLogTable[206] := 83;
  918. FLogTable[207] := 166;
  919. FLogTable[208] := 81;
  920. FLogTable[209] := 162;
  921. FLogTable[210] := 89;
  922. FLogTable[211] := 178;
  923. FLogTable[212] := 121;
  924. FLogTable[213] := 242;
  925. FLogTable[214] := 249;
  926. FLogTable[215] := 239;
  927. FLogTable[216] := 195;
  928. FLogTable[217] := 155;
  929. FLogTable[218] := 43;
  930. FLogTable[219] := 86;
  931. FLogTable[220] := 172;
  932. FLogTable[221] := 69;
  933. FLogTable[222] := 138;
  934. FLogTable[223] := 9;
  935. FLogTable[224] := 18;
  936. FLogTable[225] := 36;
  937. FLogTable[226] := 72;
  938. FLogTable[227] := 144;
  939. FLogTable[228] := 61;
  940. FLogTable[229] := 122;
  941. FLogTable[230] := 244;
  942. FLogTable[231] := 245;
  943. FLogTable[232] := 247;
  944. FLogTable[233] := 243;
  945. FLogTable[234] := 251;
  946. FLogTable[235] := 235;
  947. FLogTable[236] := 203;
  948. FLogTable[237] := 139;
  949. FLogTable[238] := 11;
  950. FLogTable[239] := 22;
  951. FLogTable[240] := 44;
  952. FLogTable[241] := 88;
  953. FLogTable[242] := 176;
  954. FLogTable[243] := 125;
  955. FLogTable[244] := 250;
  956. FLogTable[245] := 233;
  957. FLogTable[246] := 207;
  958. FLogTable[247] := 131;
  959. FLogTable[248] := 27;
  960. FLogTable[249] := 54;
  961. FLogTable[250] := 108;
  962. FLogTable[251] := 216;
  963. FLogTable[252] := 173;
  964. FLogTable[253] := 71;
  965. FLogTable[254] := 142;
  966. FLogTable[255] := 1;
  967. SetLength(FAntilogTable, 256);
  968. FAntilogTable[1] := 0;
  969. FAntilogTable[2] := 1;
  970. FAntilogTable[3] := 25;
  971. FAntilogTable[4] := 2;
  972. FAntilogTable[5] := 50;
  973. FAntilogTable[6] := 26;
  974. FAntilogTable[7] := 198;
  975. FAntilogTable[8] := 3;
  976. FAntilogTable[9] := 223;
  977. FAntilogTable[10] := 51;
  978. FAntilogTable[11] := 238;
  979. FAntilogTable[12] := 27;
  980. FAntilogTable[13] := 104;
  981. FAntilogTable[14] := 199;
  982. FAntilogTable[15] := 75;
  983. FAntilogTable[16] := 4;
  984. FAntilogTable[17] := 100;
  985. FAntilogTable[18] := 224;
  986. FAntilogTable[19] := 14;
  987. FAntilogTable[20] := 52;
  988. FAntilogTable[21] := 141;
  989. FAntilogTable[22] := 239;
  990. FAntilogTable[23] := 129;
  991. FAntilogTable[24] := 28;
  992. FAntilogTable[25] := 193;
  993. FAntilogTable[26] := 105;
  994. FAntilogTable[27] := 248;
  995. FAntilogTable[28] := 200;
  996. FAntilogTable[29] := 8;
  997. FAntilogTable[30] := 76;
  998. FAntilogTable[31] := 113;
  999. FAntilogTable[32] := 5;
  1000. FAntilogTable[33] := 138;
  1001. FAntilogTable[34] := 101;
  1002. FAntilogTable[35] := 47;
  1003. FAntilogTable[36] := 225;
  1004. FAntilogTable[37] := 36;
  1005. FAntilogTable[38] := 15;
  1006. FAntilogTable[39] := 33;
  1007. FAntilogTable[40] := 53;
  1008. FAntilogTable[41] := 147;
  1009. FAntilogTable[42] := 142;
  1010. FAntilogTable[43] := 218;
  1011. FAntilogTable[44] := 240;
  1012. FAntilogTable[45] := 18;
  1013. FAntilogTable[46] := 130;
  1014. FAntilogTable[47] := 69;
  1015. FAntilogTable[48] := 29;
  1016. FAntilogTable[49] := 181;
  1017. FAntilogTable[50] := 194;
  1018. FAntilogTable[51] := 125;
  1019. FAntilogTable[52] := 106;
  1020. FAntilogTable[53] := 39;
  1021. FAntilogTable[54] := 249;
  1022. FAntilogTable[55] := 185;
  1023. FAntilogTable[56] := 201;
  1024. FAntilogTable[57] := 154;
  1025. FAntilogTable[58] := 9;
  1026. FAntilogTable[59] := 120;
  1027. FAntilogTable[60] := 77;
  1028. FAntilogTable[61] := 228;
  1029. FAntilogTable[62] := 114;
  1030. FAntilogTable[63] := 166;
  1031. FAntilogTable[64] := 6;
  1032. FAntilogTable[65] := 191;
  1033. FAntilogTable[66] := 139;
  1034. FAntilogTable[67] := 98;
  1035. FAntilogTable[68] := 102;
  1036. FAntilogTable[69] := 221;
  1037. FAntilogTable[70] := 48;
  1038. FAntilogTable[71] := 253;
  1039. FAntilogTable[72] := 226;
  1040. FAntilogTable[73] := 152;
  1041. FAntilogTable[74] := 37;
  1042. FAntilogTable[75] := 179;
  1043. FAntilogTable[76] := 16;
  1044. FAntilogTable[77] := 145;
  1045. FAntilogTable[78] := 34;
  1046. FAntilogTable[79] := 136;
  1047. FAntilogTable[80] := 54;
  1048. FAntilogTable[81] := 208;
  1049. FAntilogTable[82] := 148;
  1050. FAntilogTable[83] := 206;
  1051. FAntilogTable[84] := 143;
  1052. FAntilogTable[85] := 150;
  1053. FAntilogTable[86] := 219;
  1054. FAntilogTable[87] := 189;
  1055. FAntilogTable[88] := 241;
  1056. FAntilogTable[89] := 210;
  1057. FAntilogTable[90] := 19;
  1058. FAntilogTable[91] := 92;
  1059. FAntilogTable[92] := 131;
  1060. FAntilogTable[93] := 56;
  1061. FAntilogTable[94] := 70;
  1062. FAntilogTable[95] := 64;
  1063. FAntilogTable[96] := 30;
  1064. FAntilogTable[97] := 66;
  1065. FAntilogTable[98] := 182;
  1066. FAntilogTable[99] := 163;
  1067. FAntilogTable[100] := 195;
  1068. FAntilogTable[101] := 72;
  1069. FAntilogTable[102] := 126;
  1070. FAntilogTable[103] := 110;
  1071. FAntilogTable[104] := 107;
  1072. FAntilogTable[105] := 58;
  1073. FAntilogTable[106] := 40;
  1074. FAntilogTable[107] := 84;
  1075. FAntilogTable[108] := 250;
  1076. FAntilogTable[109] := 133;
  1077. FAntilogTable[110] := 186;
  1078. FAntilogTable[111] := 61;
  1079. FAntilogTable[112] := 202;
  1080. FAntilogTable[113] := 94;
  1081. FAntilogTable[114] := 155;
  1082. FAntilogTable[115] := 159;
  1083. FAntilogTable[116] := 10;
  1084. FAntilogTable[117] := 21;
  1085. FAntilogTable[118] := 121;
  1086. FAntilogTable[119] := 43;
  1087. FAntilogTable[120] := 78;
  1088. FAntilogTable[121] := 212;
  1089. FAntilogTable[122] := 229;
  1090. FAntilogTable[123] := 172;
  1091. FAntilogTable[124] := 115;
  1092. FAntilogTable[125] := 243;
  1093. FAntilogTable[126] := 167;
  1094. FAntilogTable[127] := 87;
  1095. FAntilogTable[128] := 7;
  1096. FAntilogTable[129] := 112;
  1097. FAntilogTable[130] := 192;
  1098. FAntilogTable[131] := 247;
  1099. FAntilogTable[132] := 140;
  1100. FAntilogTable[133] := 128;
  1101. FAntilogTable[134] := 99;
  1102. FAntilogTable[135] := 13;
  1103. FAntilogTable[136] := 103;
  1104. FAntilogTable[137] := 74;
  1105. FAntilogTable[138] := 222;
  1106. FAntilogTable[139] := 237;
  1107. FAntilogTable[140] := 49;
  1108. FAntilogTable[141] := 197;
  1109. FAntilogTable[142] := 254;
  1110. FAntilogTable[143] := 24;
  1111. FAntilogTable[144] := 227;
  1112. FAntilogTable[145] := 165;
  1113. FAntilogTable[146] := 153;
  1114. FAntilogTable[147] := 119;
  1115. FAntilogTable[148] := 38;
  1116. FAntilogTable[149] := 184;
  1117. FAntilogTable[150] := 180;
  1118. FAntilogTable[151] := 124;
  1119. FAntilogTable[152] := 17;
  1120. FAntilogTable[153] := 68;
  1121. FAntilogTable[154] := 146;
  1122. FAntilogTable[155] := 217;
  1123. FAntilogTable[156] := 35;
  1124. FAntilogTable[157] := 32;
  1125. FAntilogTable[158] := 137;
  1126. FAntilogTable[159] := 46;
  1127. FAntilogTable[160] := 55;
  1128. FAntilogTable[161] := 63;
  1129. FAntilogTable[162] := 209;
  1130. FAntilogTable[163] := 91;
  1131. FAntilogTable[164] := 149;
  1132. FAntilogTable[165] := 188;
  1133. FAntilogTable[166] := 207;
  1134. FAntilogTable[167] := 205;
  1135. FAntilogTable[168] := 144;
  1136. FAntilogTable[169] := 135;
  1137. FAntilogTable[170] := 151;
  1138. FAntilogTable[171] := 178;
  1139. FAntilogTable[172] := 220;
  1140. FAntilogTable[173] := 252;
  1141. FAntilogTable[174] := 190;
  1142. FAntilogTable[175] := 97;
  1143. FAntilogTable[176] := 242;
  1144. FAntilogTable[177] := 86;
  1145. FAntilogTable[178] := 211;
  1146. FAntilogTable[179] := 171;
  1147. FAntilogTable[180] := 20;
  1148. FAntilogTable[181] := 42;
  1149. FAntilogTable[182] := 93;
  1150. FAntilogTable[183] := 158;
  1151. FAntilogTable[184] := 132;
  1152. FAntilogTable[185] := 60;
  1153. FAntilogTable[186] := 57;
  1154. FAntilogTable[187] := 83;
  1155. FAntilogTable[188] := 71;
  1156. FAntilogTable[189] := 109;
  1157. FAntilogTable[190] := 65;
  1158. FAntilogTable[191] := 162;
  1159. FAntilogTable[192] := 31;
  1160. FAntilogTable[193] := 45;
  1161. FAntilogTable[194] := 67;
  1162. FAntilogTable[195] := 216;
  1163. FAntilogTable[196] := 183;
  1164. FAntilogTable[197] := 123;
  1165. FAntilogTable[198] := 164;
  1166. FAntilogTable[199] := 118;
  1167. FAntilogTable[200] := 196;
  1168. FAntilogTable[201] := 23;
  1169. FAntilogTable[202] := 73;
  1170. FAntilogTable[203] := 236;
  1171. FAntilogTable[204] := 127;
  1172. FAntilogTable[205] := 12;
  1173. FAntilogTable[206] := 111;
  1174. FAntilogTable[207] := 246;
  1175. FAntilogTable[208] := 108;
  1176. FAntilogTable[209] := 161;
  1177. FAntilogTable[210] := 59;
  1178. FAntilogTable[211] := 82;
  1179. FAntilogTable[212] := 41;
  1180. FAntilogTable[213] := 157;
  1181. FAntilogTable[214] := 85;
  1182. FAntilogTable[215] := 170;
  1183. FAntilogTable[216] := 251;
  1184. FAntilogTable[217] := 96;
  1185. FAntilogTable[218] := 134;
  1186. FAntilogTable[219] := 177;
  1187. FAntilogTable[220] := 187;
  1188. FAntilogTable[221] := 204;
  1189. FAntilogTable[222] := 62;
  1190. FAntilogTable[223] := 90;
  1191. FAntilogTable[224] := 203;
  1192. FAntilogTable[225] := 89;
  1193. FAntilogTable[226] := 95;
  1194. FAntilogTable[227] := 176;
  1195. FAntilogTable[228] := 156;
  1196. FAntilogTable[229] := 169;
  1197. FAntilogTable[230] := 160;
  1198. FAntilogTable[231] := 81;
  1199. FAntilogTable[232] := 11;
  1200. FAntilogTable[233] := 245;
  1201. FAntilogTable[234] := 22;
  1202. FAntilogTable[235] := 235;
  1203. FAntilogTable[236] := 122;
  1204. FAntilogTable[237] := 117;
  1205. FAntilogTable[238] := 44;
  1206. FAntilogTable[239] := 215;
  1207. FAntilogTable[240] := 79;
  1208. FAntilogTable[241] := 174;
  1209. FAntilogTable[242] := 213;
  1210. FAntilogTable[243] := 233;
  1211. FAntilogTable[244] := 230;
  1212. FAntilogTable[245] := 231;
  1213. FAntilogTable[246] := 173;
  1214. FAntilogTable[247] := 232;
  1215. FAntilogTable[248] := 116;
  1216. FAntilogTable[249] := 214;
  1217. FAntilogTable[250] := 244;
  1218. FAntilogTable[251] := 234;
  1219. FAntilogTable[252] := 168;
  1220. FAntilogTable[253] := 80;
  1221. FAntilogTable[254] := 88;
  1222. FAntilogTable[255] := 175;
  1223. PixelsPerModule := 15;
  1224. end;
  1225. function TQRCode.DecimalToBinary(value, digits: integer): string;
  1226. var
  1227. i: integer;
  1228. begin
  1229. if digits > 32 then
  1230. digits := 32;
  1231. Result := '';
  1232. i := 0;
  1233. while i < digits do
  1234. begin
  1235. if ((1 shl i) and value) > 0 then
  1236. Result := '1' + Result
  1237. else
  1238. Result := '0' + Result;
  1239. inc(i);
  1240. end;
  1241. end;
  1242. destructor TQRCode.Destroy;
  1243. begin
  1244. FReservedAreas.Free;
  1245. inherited;
  1246. end;
  1247. function TQRCode.DetermineQRMode : TQRMode;
  1248. var
  1249. i: Integer;
  1250. begin
  1251. Result := TQRMode.Numeric;
  1252. if length(FData) = 0 then
  1253. exit;
  1254. for i := 0 to Length(FData)-1 do
  1255. if (not CharInSet(Char(FData[i]), ['0'..'9'])) then
  1256. begin
  1257. if (not CharInSet(Char(FData[i]),['0'..'9', 'A'..'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'])) then
  1258. begin
  1259. (*if {(Ord(s.Chars[i]) > 256) or }(TEncoding.UTF8.GetString(FData) <> TEncoding.Unicode.GetString(FData)) then
  1260. begin
  1261. Result := TQRMode.Kanji;
  1262. end else if (Result < TQRMode.Byte) then*)
  1263. Result := TQRMode.Byte;
  1264. end else if (Result < TQRMode.AlphaNumeric) then
  1265. Result := TQRMode.AlphaNumeric;
  1266. end;
  1267. end;
  1268. procedure TQRCode.DrawModules;
  1269. procedure DrawFinder(fp : TFinderPosition);
  1270. var
  1271. pt : TPoint;
  1272. x, y: Integer;
  1273. begin
  1274. pt := FinderLocation(fp);
  1275. for x := 0 to 6 do
  1276. for y := 0 to 6 do
  1277. begin
  1278. FModules[x + pt.x][y + pt.y] :=
  1279. (x = 0) or
  1280. (x = 6) or
  1281. (y = 0) or
  1282. (y = 6) or
  1283. ((x >= 2) and (x <= 4) and (y >= 2) and (y <= 4)) // center
  1284. end;
  1285. case fp of
  1286. TFinderPosition.TopLeft: ;
  1287. TFinderPosition.TopRight:
  1288. pt.Offset(-1,0);
  1289. TFinderPosition.BottomLeft:
  1290. pt.Offset(0,-1);
  1291. end;
  1292. AddReservedArea(TRect.Create(pt,8,8));
  1293. end;
  1294. procedure DrawAlignmentPatterns;
  1295. procedure DrawAlignmentPatternAt(pt : TPoint);
  1296. var
  1297. i: Integer;
  1298. fp : TFinderPosition;
  1299. ptfp : TPoint;
  1300. rectAP : TRect;
  1301. rectFinder : TRect;
  1302. x: Integer;
  1303. y: Integer;
  1304. begin
  1305. pt.Offset(-2,-2);
  1306. rectAP := TRect.Create(pt,5,5);
  1307. for i := 0 to 2 do
  1308. begin
  1309. fp := TFinderPosition(i);
  1310. ptfp := FinderLocation(fp);
  1311. case fp of
  1312. TFinderPosition.TopRight:
  1313. ptfp.SetLocation(ptfp.X, ptfp.Y);
  1314. TFinderPosition.BottomLeft:
  1315. ptfp.SetLocation(ptfp.X, ptfp.Y);
  1316. end;
  1317. rectFinder := TRect.Create(ptfp,8,8);
  1318. if rectAP.IntersectsWithRect(rectFinder) then
  1319. exit;
  1320. end;
  1321. for x := 0 to 4 do
  1322. for y := 0 to 4 do
  1323. FModules[x + pt.x][y + pt.Y] :=
  1324. (x = 0) or
  1325. (x = 4) or
  1326. (y = 0) or
  1327. (y = 4) or
  1328. ((x = 2) and (y = 2));
  1329. AddReservedArea(TRect.Create(pt, 4,4));
  1330. end;
  1331. var
  1332. Locs : TArray<Integer>;
  1333. Points : TArray<TArray<Integer>>;
  1334. i: Integer;
  1335. idx : integer;
  1336. begin
  1337. case FVersionInUse of
  1338. TVersion.v1: SetLength(Locs,0);
  1339. TVersion.v2:
  1340. begin
  1341. SetLength(Locs,2);
  1342. Locs[0] := 6;
  1343. Locs[1] := 18;
  1344. end;
  1345. TVersion.v3:
  1346. begin
  1347. SetLength(Locs,2);
  1348. Locs[0] := 6;
  1349. Locs[1] := 22;
  1350. end;
  1351. TVersion.v4:
  1352. begin
  1353. SetLength(Locs,2);
  1354. Locs[0] := 6;
  1355. Locs[1] := 26;
  1356. end;
  1357. TVersion.v5:
  1358. begin
  1359. SetLength(Locs,2);
  1360. Locs[0] := 6;
  1361. Locs[1] := 30;
  1362. end;
  1363. TVersion.v6:
  1364. begin
  1365. SetLength(Locs,2);
  1366. Locs[0] := 6;
  1367. Locs[1] := 34;
  1368. end;
  1369. TVersion.v7:
  1370. begin
  1371. SetLength(Locs,3);
  1372. Locs[0] := 6;
  1373. Locs[1] := 22;
  1374. Locs[2] := 38;
  1375. end;
  1376. TVersion.v8:
  1377. begin
  1378. SetLength(Locs,3);
  1379. Locs[0] := 6;
  1380. Locs[1] := 24;
  1381. Locs[2] := 42;
  1382. end;
  1383. TVersion.v9:
  1384. begin
  1385. SetLength(Locs,3);
  1386. Locs[0] := 6;
  1387. Locs[1] := 26;
  1388. Locs[2] := 46;
  1389. end;
  1390. TVersion.v10:
  1391. begin
  1392. SetLength(Locs,3);
  1393. Locs[0] := 6;
  1394. Locs[1] := 28;
  1395. Locs[2] := 50;
  1396. end;
  1397. TVersion.v11:
  1398. begin
  1399. SetLength(Locs,3);
  1400. Locs[0] := 6;
  1401. Locs[1] := 30;
  1402. Locs[2] := 54;
  1403. end;
  1404. TVersion.v12:
  1405. begin
  1406. SetLength(Locs,3);
  1407. Locs[0] := 6;
  1408. Locs[1] := 32;
  1409. Locs[2] := 58;
  1410. end;
  1411. TVersion.v13:
  1412. begin
  1413. SetLength(Locs,3);
  1414. Locs[0] := 6;
  1415. Locs[1] := 34;
  1416. Locs[2] := 62;
  1417. end;
  1418. TVersion.v14:
  1419. begin
  1420. SetLength(Locs,4);
  1421. Locs[0] := 6;
  1422. Locs[1] := 26;
  1423. Locs[2] := 46;
  1424. Locs[3] := 66;
  1425. end;
  1426. TVersion.v15:
  1427. begin
  1428. SetLength(Locs,4);
  1429. Locs[0] := 6;
  1430. Locs[1] := 26;
  1431. Locs[2] := 48;
  1432. Locs[3] := 70;
  1433. end;
  1434. TVersion.v16:
  1435. begin
  1436. SetLength(Locs,4);
  1437. Locs[0] := 6;
  1438. Locs[1] := 26;
  1439. Locs[2] := 50;
  1440. Locs[3] := 74;
  1441. end;
  1442. TVersion.v17:
  1443. begin
  1444. SetLength(Locs,4);
  1445. Locs[0] := 6;
  1446. Locs[1] := 30;
  1447. Locs[2] := 54;
  1448. Locs[3] := 78;
  1449. end;
  1450. TVersion.v18:
  1451. begin
  1452. SetLength(Locs,4);
  1453. Locs[0] := 6;
  1454. Locs[1] := 30;
  1455. Locs[2] := 56;
  1456. Locs[3] := 82;
  1457. end;
  1458. TVersion.v19:
  1459. begin
  1460. SetLength(Locs,4);
  1461. Locs[0] := 6;
  1462. Locs[1] := 30;
  1463. Locs[2] := 58;
  1464. Locs[3] := 86;
  1465. end;
  1466. TVersion.v20:
  1467. begin
  1468. SetLength(Locs,4);
  1469. Locs[0] := 6;
  1470. Locs[1] := 34;
  1471. Locs[2] := 62;
  1472. Locs[3] := 90;
  1473. end;
  1474. TVersion.v21:
  1475. begin
  1476. SetLength(Locs,5);
  1477. Locs[0] := 6;
  1478. Locs[1] := 28;
  1479. Locs[2] := 50;
  1480. Locs[3] := 72;
  1481. Locs[4] := 94;
  1482. end;
  1483. TVersion.v22:
  1484. begin
  1485. SetLength(Locs,5);
  1486. Locs[0] := 6;
  1487. Locs[1] := 26;
  1488. Locs[2] := 50;
  1489. Locs[3] := 74;
  1490. Locs[4] := 98;
  1491. end;
  1492. TVersion.v23:
  1493. begin
  1494. SetLength(Locs,5);
  1495. Locs[0] := 6;
  1496. Locs[1] := 30;
  1497. Locs[2] := 54;
  1498. Locs[3] := 78;
  1499. Locs[4] := 102;
  1500. end;
  1501. TVersion.v24:
  1502. begin
  1503. SetLength(Locs,5);
  1504. Locs[0] := 6;
  1505. Locs[1] := 28;
  1506. Locs[2] := 54;
  1507. Locs[3] := 80;
  1508. Locs[4] := 106;
  1509. end;
  1510. TVersion.v25:
  1511. begin
  1512. SetLength(Locs,5);
  1513. Locs[0] := 6;
  1514. Locs[1] := 32;
  1515. Locs[2] := 58;
  1516. Locs[3] := 84;
  1517. Locs[4] := 110;
  1518. end;
  1519. TVersion.v26:
  1520. begin
  1521. SetLength(Locs,5);
  1522. Locs[0] := 6;
  1523. Locs[1] := 30;
  1524. Locs[2] := 58;
  1525. Locs[3] := 86;
  1526. Locs[4] := 114;
  1527. end;
  1528. TVersion.v27:
  1529. begin
  1530. SetLength(Locs,5);
  1531. Locs[0] := 6;
  1532. Locs[1] := 34;
  1533. Locs[2] := 62;
  1534. Locs[3] := 90;
  1535. Locs[4] := 118;
  1536. end;
  1537. TVersion.v28:
  1538. begin
  1539. SetLength(Locs,6);
  1540. Locs[0] := 6;
  1541. Locs[1] := 26;
  1542. Locs[2] := 50;
  1543. Locs[3] := 74;
  1544. Locs[4] := 98;
  1545. Locs[5] := 122;
  1546. end;
  1547. TVersion.v29:
  1548. begin
  1549. SetLength(Locs,6);
  1550. Locs[0] := 6;
  1551. Locs[1] := 30;
  1552. Locs[2] := 54;
  1553. Locs[3] := 78;
  1554. Locs[4] := 102;
  1555. Locs[5] := 126;
  1556. end;
  1557. TVersion.v30:
  1558. begin
  1559. SetLength(Locs,6);
  1560. Locs[0] := 6;
  1561. Locs[1] := 26;
  1562. Locs[2] := 52;
  1563. Locs[3] := 78;
  1564. Locs[4] := 104;
  1565. Locs[5] := 130;
  1566. end;
  1567. TVersion.v31:
  1568. begin
  1569. SetLength(Locs,6);
  1570. Locs[0] := 6;
  1571. Locs[1] := 30;
  1572. Locs[2] := 56;
  1573. Locs[3] := 82;
  1574. Locs[4] := 108;
  1575. Locs[5] := 134;
  1576. end;
  1577. TVersion.v32:
  1578. begin
  1579. SetLength(Locs,6);
  1580. Locs[0] := 6;
  1581. Locs[1] := 34;
  1582. Locs[2] := 60;
  1583. Locs[3] := 86;
  1584. Locs[4] := 112;
  1585. Locs[5] := 138;
  1586. end;
  1587. TVersion.v33:
  1588. begin
  1589. SetLength(Locs,6);
  1590. Locs[0] := 6;
  1591. Locs[1] := 30;
  1592. Locs[2] := 58;
  1593. Locs[3] := 86;
  1594. Locs[4] := 114;
  1595. Locs[5] := 142;
  1596. end;
  1597. TVersion.v34:
  1598. begin
  1599. SetLength(Locs,6);
  1600. Locs[0] := 6;
  1601. Locs[1] := 34;
  1602. Locs[2] := 62;
  1603. Locs[3] := 90;
  1604. Locs[4] := 118;
  1605. Locs[5] := 146;
  1606. end;
  1607. TVersion.v35:
  1608. begin
  1609. SetLength(Locs,7);
  1610. Locs[0] := 6;
  1611. Locs[1] := 30;
  1612. Locs[2] := 54;
  1613. Locs[3] := 78;
  1614. Locs[4] := 102;
  1615. Locs[5] := 126;
  1616. Locs[6] := 150;
  1617. end;
  1618. TVersion.v36:
  1619. begin
  1620. SetLength(Locs,7);
  1621. Locs[0] := 6;
  1622. Locs[1] := 24;
  1623. Locs[2] := 50;
  1624. Locs[3] := 76;
  1625. Locs[4] := 102;
  1626. Locs[5] := 128;
  1627. Locs[6] := 154;
  1628. end;
  1629. TVersion.v37:
  1630. begin
  1631. SetLength(Locs,7);
  1632. Locs[0] := 6;
  1633. Locs[1] := 28;
  1634. Locs[2] := 54;
  1635. Locs[3] := 80;
  1636. Locs[4] := 106;
  1637. Locs[5] := 132;
  1638. Locs[6] := 158;
  1639. end;
  1640. TVersion.v38:
  1641. begin
  1642. SetLength(Locs,7);
  1643. Locs[0] := 6;
  1644. Locs[1] := 32;
  1645. Locs[2] := 58;
  1646. Locs[3] := 84;
  1647. Locs[4] := 110;
  1648. Locs[5] := 136;
  1649. Locs[6] := 162;
  1650. end;
  1651. TVersion.v39:
  1652. begin
  1653. SetLength(Locs,7);
  1654. Locs[0] := 6;
  1655. Locs[1] := 26;
  1656. Locs[2] := 54;
  1657. Locs[3] := 82;
  1658. Locs[4] := 110;
  1659. Locs[5] := 138;
  1660. Locs[6] := 166;
  1661. end;
  1662. TVersion.v40:
  1663. begin
  1664. SetLength(Locs,7);
  1665. Locs[0] := 6;
  1666. Locs[1] := 30;
  1667. Locs[2] := 58;
  1668. Locs[3] := 86;
  1669. Locs[4] := 114;
  1670. Locs[5] := 142;
  1671. Locs[6] := 170;
  1672. end;
  1673. end;
  1674. if Length(Locs) > 0 then
  1675. begin
  1676. Points := TArrayHelper<Integer>.Combination(Locs, 2);
  1677. SetLength(Points, Length(Points)+Length(Locs));
  1678. for i := Length(Locs)-1 downto 0 do
  1679. begin
  1680. setLength(Points[Length(Points)-i-1],2);
  1681. Points[Length(Points)-i-1][0] := Locs[i];
  1682. Points[Length(Points)-i-1][1] := Locs[i];
  1683. end;
  1684. for i := Length(Points)-1 downto 0 do
  1685. begin
  1686. if Points[i][0] <> Points[i][1] then
  1687. begin
  1688. SetLength(Points, length(Points)+1);
  1689. idx := length(Points)-1;
  1690. SetLength(Points[idx],2);
  1691. Points[idx][0] := Points[i][1];
  1692. Points[idx][1] := Points[i][0];
  1693. end;
  1694. end;
  1695. for i := 0 to length(Points)-1 do
  1696. begin
  1697. DrawAlignmentPatternAt(TPoint.Create(Points[i][0], Points[i][1]));
  1698. end;
  1699. end;
  1700. end;
  1701. procedure DrawTimingPatterns;
  1702. var
  1703. x, y: Integer;
  1704. begin
  1705. y := 6;
  1706. for x := 8 to Size-9 do
  1707. begin
  1708. FModules[x][y] := (x+1) mod 2 <> 0;
  1709. FModules[y][x] := (x+1) mod 2 <> 0;
  1710. end;
  1711. end;
  1712. procedure DrawDarkModule;
  1713. var
  1714. pt : TPoint;
  1715. begin
  1716. pt := FinderLocation(TFinderPosition.BottomLeft);
  1717. pt.Offset(8,-1);
  1718. FModules[pt.X][pt.Y] := True;
  1719. AddReservedArea(TRect.Create(pt,0,0));
  1720. end;
  1721. procedure ReserveFormatArea;
  1722. begin
  1723. AddReservedArea(TRect.Create(0,8, 8, 8));
  1724. AddReservedArea(TRect.Create(8,0, 8, 8));
  1725. AddReservedArea(TRect.Create(8,FinderLocation(TFinderPosition.BottomLeft).Y,8,FinderLocation(TFinderPosition.BottomLeft).Y+8));
  1726. AddReservedArea(TRect.Create(FinderLocation(TFinderPosition.TopRight).X-1,8, FinderLocation(TFinderPosition.TopRight).X+7,8));
  1727. end;
  1728. procedure ReserveVersionArea;
  1729. begin
  1730. if FVersionInUse >= TVersion.v7 then
  1731. begin
  1732. AddReservedArea(TRect.Create(FinderLocation(TFinderPosition.TopRight).X-4,0,FinderLocation(TFinderPosition.TopRight).X-2,5));
  1733. AddReservedArea(TRect.Create(0, FinderLocation(TFinderPosition.BottomLeft).Y-4,5,FinderLocation(TFinderPosition.BottomLeft).Y-2));
  1734. end;
  1735. end;
  1736. function IsPointReserved(pt : TPoint) : Boolean;
  1737. var
  1738. i: Integer;
  1739. begin
  1740. Result := (pt.x = 6) or (pt.y = 6);
  1741. if not Result then
  1742. for i := 0 to FReservedAreas.Count-1 do
  1743. if FReservedAreas[i].IntersectsWithPoint(pt) then
  1744. begin
  1745. Result := True;
  1746. exit;
  1747. end;
  1748. end;
  1749. procedure DrawDataBits;
  1750. var
  1751. x, y, idx : integer;
  1752. begin
  1753. x := Size-1;
  1754. idx := 0;
  1755. repeat
  1756. y := Size-1;
  1757. repeat
  1758. if y = 6 then
  1759. begin
  1760. dec(y);
  1761. continue;
  1762. end;
  1763. if idx < DataBits.Length then
  1764. begin
  1765. if not IsPointReserved(TPoint.Create(x,y)) then
  1766. begin
  1767. FModules[x,y] := DataBits.Chars[idx] = '1';
  1768. inc(idx);
  1769. end;
  1770. end;
  1771. if idx < DataBits.Length then
  1772. begin
  1773. if not IsPointReserved(TPoint.Create(x-1,y)) then
  1774. begin
  1775. FModules[x-1,y] := DataBits.Chars[idx] = '1';
  1776. inc(idx);
  1777. end;
  1778. end;
  1779. dec(y);
  1780. until y<0;
  1781. dec(x,2);
  1782. if x = 6 then
  1783. dec(x);
  1784. y := 0;
  1785. repeat
  1786. if y = 6 then
  1787. begin
  1788. inc(y);
  1789. continue;
  1790. end;
  1791. if idx < DataBits.Length then
  1792. begin
  1793. if not IsPointReserved(TPoint.Create(x,y)) then
  1794. begin
  1795. FModules[x,y] := DataBits.Chars[idx] = '1';
  1796. inc(idx);
  1797. end;
  1798. end;
  1799. if idx < DataBits.Length then
  1800. begin
  1801. if not IsPointReserved(TPoint.Create(x-1,y)) then
  1802. begin
  1803. FModules[x-1,y] := DataBits.Chars[idx] = '1';
  1804. inc(idx);
  1805. end;
  1806. end;
  1807. inc(y);
  1808. until y >= Size;
  1809. dec(x,2);
  1810. if x = 6 then
  1811. dec(x);
  1812. until (x<0);
  1813. end;
  1814. procedure DrawMaskPattern;
  1815. procedure ApplyMask(Pattern : TMask; var ary : TArray<TArray<Boolean>>);
  1816. var
  1817. x: Integer;
  1818. y: Integer;
  1819. pt : TPoint;
  1820. begin
  1821. if Pattern = TMask.Auto then
  1822. raise EQREncodeException.Create('Cannot apply invalid mask.');
  1823. for y := 0 to Size-1 do
  1824. for x := 0 to Size-1 do
  1825. begin
  1826. pt := TPoint.Create(x, y);;
  1827. if not IsPointReserved(pt) then
  1828. begin
  1829. case Integer(Pattern) of
  1830. 0: if (y + x) mod 2 = 0 then
  1831. ary[x][y] := not ary[x][y];
  1832. 1: if (y) mod 2 = 0 then
  1833. ary[x][y] := not ary[x][y];
  1834. 2: if (x) mod 3 = 0 then
  1835. ary[x][y] := not ary[x][y];
  1836. 3: if (y + x) mod 3 = 0 then
  1837. ary[x][y] := not ary[x][y];
  1838. 4: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
  1839. ary[x][y] := not ary[x][y];
  1840. 5: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
  1841. ary[x][y] := not ary[x][y];
  1842. 6: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
  1843. ary[x][y] := not ary[x][y];
  1844. 7: if ( floor(y / 2) + floor(x / 3) ) mod 2 = 0 then
  1845. ary[x][y] := not ary[x][y];
  1846. end;
  1847. end;
  1848. end;
  1849. FMaskInUse := Pattern;
  1850. end;
  1851. function PenaltyScore(Mask : integer; ary : TArray<TArray<Boolean>>) : integer;
  1852. function PenaltyTest1 : integer;
  1853. var
  1854. y, x: Integer;
  1855. iColorCnt : integer;
  1856. bLastColor : boolean;
  1857. begin
  1858. Result := 0;
  1859. for y := 0 to Size-1 do
  1860. begin
  1861. iColorCnt := 1;
  1862. bLastColor := ary[0][y];
  1863. for x := 1 to Size-1 do
  1864. begin
  1865. if ary[x][y] = bLastColor then
  1866. begin
  1867. inc(iColorCnt);
  1868. if iColorCnt = 5 then
  1869. inc(Result,3)
  1870. else if iColorCnt > 5 then
  1871. inc(Result,1);
  1872. end else
  1873. begin
  1874. iColorCnt := 1;
  1875. bLastColor := not bLastColor;
  1876. end;
  1877. end;
  1878. end;
  1879. for x := 0 to Size-1 do
  1880. begin
  1881. iColorCnt := 1;
  1882. bLastColor := ary[x][0];
  1883. for y := 1 to Size-1 do
  1884. begin
  1885. if ary[x][y] = bLastColor then
  1886. begin
  1887. inc(iColorCnt);
  1888. if iColorCnt = 5 then
  1889. inc(Result,3)
  1890. else if iColorCnt > 5 then
  1891. inc(Result,1);
  1892. end else
  1893. begin
  1894. iColorCnt := 1;
  1895. bLastColor := not bLastColor;
  1896. end;
  1897. end;
  1898. end;
  1899. end;
  1900. function PenaltyTest2 : integer;
  1901. var
  1902. y, x: Integer;
  1903. begin
  1904. Result := 0;
  1905. for x := 0 to Size-2 do
  1906. for y := 0 to Size-2 do
  1907. begin
  1908. if (ary[x][y] = ary[x+1][y]) and
  1909. (ary[x][y] = ary[x][y+1]) and
  1910. (ary[x][y] = ary[x+1][y+1]) then
  1911. inc(Result,3);
  1912. end;
  1913. end;
  1914. function PenaltyTest3 : integer;
  1915. var
  1916. y, x: Integer;
  1917. begin
  1918. Result := 0;
  1919. for y := 0 to Size-1 do
  1920. for x := 0 to Size-12 do
  1921. begin
  1922. 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
  1923. ((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
  1924. inc(Result,40);
  1925. end;
  1926. for x := 0 to Size-1 do
  1927. for y := 0 to Size-12 do
  1928. begin
  1929. 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
  1930. ((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
  1931. inc(Result,40);
  1932. end;
  1933. end;
  1934. function PenaltyTest4 : integer;
  1935. var
  1936. x: Integer;
  1937. y: Integer;
  1938. iCnt, iColor : integer;
  1939. iPercent, iLow, iHigh : integer;
  1940. begin
  1941. iCnt := 0;
  1942. iColor := 0;
  1943. for x := 0 to Size-1 do
  1944. for y := 0 to Size-1 do
  1945. begin
  1946. inc(iCnt);
  1947. if ary[x][y] then
  1948. inc(iColor);
  1949. end;
  1950. if iCnt = 0 then
  1951. begin
  1952. result := 0;
  1953. exit;
  1954. end;
  1955. iPercent := Trunc((iColor / iCnt) * 100);
  1956. iLow := iPercent -1;
  1957. iHigh := iPercent +1;
  1958. while iLow mod 5 <> 0 do
  1959. dec(iLow);
  1960. while iHigh mod 5 <> 0 do
  1961. inc(iHigh);
  1962. Result := Min(Abs(iLow-50), Abs(iHigh-50))*10;
  1963. end;
  1964. begin
  1965. FPenaltyScores[Mask][0] := PenaltyTest1;
  1966. FPenaltyScores[Mask][1] := PenaltyTest2;
  1967. FPenaltyScores[Mask][2] := PenaltyTest3;
  1968. FPenaltyScores[Mask][3] := PenaltyTest4;
  1969. Result :=
  1970. FPenaltyScores[Mask][0] +
  1971. FPenaltyScores[Mask][1] +
  1972. FPenaltyScores[Mask][2] +
  1973. FPenaltyScores[Mask][3] ;
  1974. end;
  1975. var
  1976. ary : TArray<TArray<Boolean>>;
  1977. iScore, iLowScore, iSelected : integer;
  1978. i, x, y: Integer;
  1979. begin
  1980. iSelected := 0;
  1981. iLowScore := High(Integer);
  1982. for i := 0 to 7 do
  1983. begin
  1984. SetLength(ary, Length(FModules));
  1985. for y := 0 to Length(FModules)-1 do
  1986. begin
  1987. SetLength(ary[y], Length(FModules[y]));
  1988. end;
  1989. for y := 0 to Length(FModules)-1 do
  1990. begin
  1991. for x := 0 to length(FModules[y])-1 do
  1992. ary[x][y] := FModules[x][y];
  1993. end;
  1994. ApplyMask(TMask(i), ary);
  1995. iScore := PenaltyScore(i, ary);
  1996. if iScore < iLowScore then
  1997. begin
  1998. iLowScore := iScore;
  1999. iSelected := i;
  2000. end;
  2001. end;
  2002. if FMask = TMask.Auto then
  2003. ApplyMask(TMask(iSelected), FModules)
  2004. else
  2005. ApplyMask(FMask, FModules);
  2006. end;
  2007. procedure DrawFormat;
  2008. function FormatString : string;
  2009. begin
  2010. case FECLInUse of
  2011. TErrorCorrectionLevel.Low:
  2012. case Integer(FMaskInUse) of
  2013. 0: Result := '111011111000100';
  2014. 1: Result := '111001011110011';
  2015. 2: Result := '111110110101010';
  2016. 3: Result := '111100010011101';
  2017. 4: Result := '110011000101111';
  2018. 5: Result := '110001100011000';
  2019. 6: Result := '110110001000001';
  2020. 7: Result := '110100101110110';
  2021. end;
  2022. TErrorCorrectionLevel.Medium:
  2023. case Integer(FMaskInUse) of
  2024. 0: Result := '101010000010010';
  2025. 1: Result := '101000100100101';
  2026. 2: Result := '101111001111100';
  2027. 3: Result := '101101101001011';
  2028. 4: Result := '100010111111001';
  2029. 5: Result := '100000011001110';
  2030. 6: Result := '100111110010111';
  2031. 7: Result := '100101010100000';
  2032. end;
  2033. TErrorCorrectionLevel.Quartile:
  2034. case Integer(FMaskInUse) of
  2035. 0: Result := '011010101011111';
  2036. 1: Result := '011000001101000';
  2037. 2: Result := '011111100110001';
  2038. 3: Result := '011101000000110';
  2039. 4: Result := '010010010110100';
  2040. 5: Result := '010000110000011';
  2041. 6: Result := '010111011011010';
  2042. 7: Result := '010101111101101';
  2043. end;
  2044. TErrorCorrectionLevel.High:
  2045. case Integer(FMaskInUse) of
  2046. 0: Result := '001011010001001';
  2047. 1: Result := '001001110111110';
  2048. 2: Result := '001110011100111';
  2049. 3: Result := '001100111010000';
  2050. 4: Result := '000011101100010';
  2051. 5: Result := '000001001010101';
  2052. 6: Result := '000110100001100';
  2053. 7: Result := '000100000111011';
  2054. end;
  2055. end;
  2056. end;
  2057. var
  2058. s : string;
  2059. sFmt : string;
  2060. x, y : integer;
  2061. y2 : integer;
  2062. x2 : integer;
  2063. begin
  2064. sFmt := FormatString;
  2065. x := 0;
  2066. y := 8;
  2067. y2 := Size-1;
  2068. x2 := 8;
  2069. for s in sFmt do
  2070. begin
  2071. FModules[x][y] := s = '1';
  2072. if x < 8 then
  2073. inc(x)
  2074. else
  2075. dec(y);
  2076. if x = 6 then
  2077. inc(x);
  2078. if y = 6 then
  2079. dec(y);
  2080. FModules[x2][y2] := s = '1';
  2081. if y2 <= Size-7 then
  2082. begin
  2083. if y2 = Size-7 then
  2084. begin
  2085. y2 := 8;
  2086. x2 := Size-8;
  2087. end else
  2088. inc(x2);
  2089. end else
  2090. dec(y2)
  2091. end;
  2092. end;
  2093. procedure DrawVersion;
  2094. var
  2095. sVer : string;
  2096. s: string;
  2097. x, y, x2, y2 : integer;
  2098. i: Integer;
  2099. begin
  2100. if FVersionInUse >= TVersion.v7 then
  2101. begin
  2102. case FVersionInUse of
  2103. TVersion.v7 : sVer := '000111110010010100';
  2104. TVersion.v8 : sVer := '001000010110111100';
  2105. TVersion.v9 : sVer := '001001101010011001';
  2106. TVersion.v10 : sVer := '001010010011010011';
  2107. TVersion.v11 : sVer := '001011101111110110';
  2108. TVersion.v12 : sVer := '001100011101100010';
  2109. TVersion.v13 : sVer := '001101100001000111';
  2110. TVersion.v14 : sVer := '001110011000001101';
  2111. TVersion.v15 : sVer := '001111100100101000';
  2112. TVersion.v16 : sVer := '010000101101111000';
  2113. TVersion.v17 : sVer := '010001010001011101';
  2114. TVersion.v18 : sVer := '010010101000010111';
  2115. TVersion.v19 : sVer := '010011010100110010';
  2116. TVersion.v20 : sVer := '010100100110100110';
  2117. TVersion.v21 : sVer := '010101011010000011';
  2118. TVersion.v22 : sVer := '010110100011001001';
  2119. TVersion.v23 : sVer := '010111011111101100';
  2120. TVersion.v24 : sVer := '011000111011000100';
  2121. TVersion.v25 : sVer := '011001000111100001';
  2122. TVersion.v26 : sVer := '011010111110101011';
  2123. TVersion.v27 : sVer := '011011000010001110';
  2124. TVersion.v28 : sVer := '011100110000011010';
  2125. TVersion.v29 : sVer := '011101001100111111';
  2126. TVersion.v30 : sVer := '011110110101110101';
  2127. TVersion.v31 : sVer := '011111001001010000';
  2128. TVersion.v32 : sVer := '100000100111010101';
  2129. TVersion.v33 : sVer := '100001011011110000';
  2130. TVersion.v34 : sVer := '100010100010111010';
  2131. TVersion.v35 : sVer := '100011011110011111';
  2132. TVersion.v36 : sVer := '100100101100001011';
  2133. TVersion.v37 : sVer := '100101010000101110';
  2134. TVersion.v38 : sVer := '100110101001100100';
  2135. TVersion.v39 : sVer := '100111010101000001';
  2136. TVersion.v40 : sVer := '101000110001101001';
  2137. end;
  2138. s := sVer;
  2139. for i := 1 to Length(sVer) do
  2140. begin
  2141. s[length(sVer)-i+1] := sVer[i];
  2142. end;
  2143. sVer := s;
  2144. x := 0;
  2145. y := FinderLocation(TFinderPosition.BottomLeft).Y-4;
  2146. x2 := FinderLocation(TFinderPosition.TopRight).X-4;
  2147. y2 := 0;
  2148. for s in sVer do
  2149. begin
  2150. FModules[x][y] := s = '1';
  2151. inc(y);
  2152. if y >= FinderLocation(TFinderPosition.BottomLeft).Y-1 then
  2153. begin
  2154. inc(x);
  2155. y := FinderLocation(TFinderPosition.BottomLeft).Y-4;
  2156. end;
  2157. FModules[x2][y2] := s = '1';
  2158. inc(x2);
  2159. if x2 >= FinderLocation(TFinderPosition.TopRight).X-1 then
  2160. begin
  2161. inc(y2);
  2162. x2 := FinderLocation(TFinderPosition.TopRight).X-4;
  2163. end;
  2164. end;
  2165. end;
  2166. end;
  2167. var
  2168. i: Integer;
  2169. fp: TFinderPosition;
  2170. j: Integer;
  2171. begin
  2172. SetLength(FModules, Size);
  2173. for i := 0 to Length(FModules) - 1 do
  2174. begin
  2175. SetLength(FModules[i], Size);
  2176. for j := 0 to Length(FModules[i])-1 do
  2177. FModules[i][j] := False;
  2178. end;
  2179. for i := 0 to 2 do
  2180. begin
  2181. fp := TFinderPosition(i);
  2182. DrawFinder(fp);
  2183. end;
  2184. DrawAlignmentPatterns;
  2185. DrawTimingPatterns;
  2186. DrawDarkModule;
  2187. ReserveFormatArea;
  2188. ReserveVersionArea;
  2189. DrawDataBits;
  2190. DrawMaskPattern;
  2191. DrawFormat;
  2192. DrawVersion;
  2193. end;
  2194. procedure TQRCode.EncodeAlphaNumeric;
  2195. function LookupAlphaVal(c : char) : integer;
  2196. var
  2197. i: Integer;
  2198. begin
  2199. Result := 0;
  2200. for i := 0 to 44 do
  2201. if AlphaEncoding[i] = c then
  2202. begin
  2203. Result := i;
  2204. break;
  2205. end;
  2206. end;
  2207. var
  2208. sSeg : string;
  2209. s: String;
  2210. iVal : integer;
  2211. begin
  2212. s := TEncoding.UTF8.GetString(FData);
  2213. while s.Length > 0 do
  2214. begin
  2215. sSeg := s.Substring(0,2);
  2216. Delete(s,1,2);
  2217. if sSeg.Length = 2 then
  2218. begin
  2219. iVal := (LookupAlphaVal(sSeg.Chars[0]) * 45)+LookupAlphaVal(sSeg.Chars[1]) ;
  2220. WriteBits(DecimalToBinary(iVal,11));
  2221. end else
  2222. begin
  2223. iVal := LookupAlphaVal(sSeg.Chars[0]);
  2224. WriteBits(DecimalToBinary(iVal,6));
  2225. end;
  2226. end;
  2227. end;
  2228. procedure TQRCode.EncodeByte;
  2229. var
  2230. i: Integer;
  2231. begin
  2232. for i := 0 to Length(FData)-1 do
  2233. WriteBits(DecimalToBinary(FData[i],8));
  2234. end;
  2235. procedure TQRCode.EncodeKanji;
  2236. begin
  2237. raise EQREncodeException.Create('Kanji is not currently supported.');
  2238. end;
  2239. procedure TQRCode.EncodeNumeric;
  2240. var
  2241. sSeg : string;
  2242. s : string;
  2243. begin
  2244. s := TEncoding.UTF8.GetString(FData);
  2245. while s.Length > 0 do
  2246. begin
  2247. sSeg := s.Substring(0,3);
  2248. Delete(s,1,3);
  2249. if (sSeg <> '') and sSeg.StartsWith('0') then
  2250. Delete(sSeg,1,1);
  2251. if (sSeg <> '') and sSeg.StartsWith('0') then
  2252. Delete(sSeg,1,1);
  2253. if sSeg = '' then
  2254. sSeg := '0';
  2255. case sSeg.Length of
  2256. 1:
  2257. WriteBits(DecimalToBinary(sSeg.ToInteger,4));
  2258. 2:
  2259. WriteBits(DecimalToBinary(sSeg.ToInteger,7));
  2260. 3:
  2261. WriteBits(DecimalToBinary(sSeg.ToInteger,10));
  2262. end;
  2263. end;
  2264. end;
  2265. procedure TQRCode.EndUpdate;
  2266. begin
  2267. dec(FUpdateDepth);
  2268. if FUpdateDepth < 0 then
  2269. FUpdateDepth := 0;
  2270. if FUpdateDepth = 0 then
  2271. UpdateCode;
  2272. end;
  2273. function TQRCode.DataCodewordCount: integer;
  2274. begin
  2275. case FECLInUse of
  2276. TErrorCorrectionLevel.Low:
  2277. Result := FCodeWordRequirements[FVersionInUse].Low[TCodeWordField.DataCodewordCount];
  2278. TErrorCorrectionLevel.Medium:
  2279. Result := FCodeWordRequirements[FVersionInUse].Medium[TCodeWordField.DataCodewordCount];
  2280. TErrorCorrectionLevel.Quartile:
  2281. Result := FCodeWordRequirements[FVersionInUse].Quartile[TCodeWordField.DataCodewordCount];
  2282. TErrorCorrectionLevel.High:
  2283. Result := FCodeWordRequirements[FVersionInUse].High[TCodeWordField.DataCodewordCount];
  2284. else
  2285. Result := 0;
  2286. end;
  2287. end;
  2288. function TQRCode.FinderLocation(pos: TFinderPosition): TPoint;
  2289. begin
  2290. case pos of
  2291. TFinderPosition.TopLeft:
  2292. Result := TPoint.Create(0,0);
  2293. TFinderPosition.TopRight:
  2294. Result := TPoint.Create((((Integer(FVersionInUse)-1)*4)+21) - 7, 0);
  2295. TFinderPosition.BottomLeft:
  2296. Result := TPoint.Create(0,(((Integer(FVersionInUse)-1)*4)+21) - 7);
  2297. end;
  2298. end;
  2299. procedure TQRCode.CalculateModules;
  2300. var
  2301. g1, g2, gECC1, gECC2 : TGroup;
  2302. blk : TBlock;
  2303. cw : Byte;
  2304. i, iBlock, iPos, iOutPos: integer;
  2305. cwf : TCodeWordFields;
  2306. iECCSize : integer;
  2307. rs : TReedSolomonGenerator;
  2308. begin
  2309. case FECLInUse of
  2310. TErrorCorrectionLevel.Low:
  2311. cwf := FCodeWordRequirements[FVersionInUse].Low;
  2312. TErrorCorrectionLevel.Medium:
  2313. cwf := FCodeWordRequirements[FVersionInUse].Medium;
  2314. TErrorCorrectionLevel.Quartile:
  2315. cwf := FCodeWordRequirements[FVersionInUse].Quartile;
  2316. TErrorCorrectionLevel.High:
  2317. cwf := FCodeWordRequirements[FVersionInUse].High;
  2318. end;
  2319. iPos := 0;
  2320. iECCSize := 0;
  2321. SetStatus('Collecting Data Codewords');
  2322. setLength(g1, cwf[TCodeWordField.BlocksInGroup1Count]);
  2323. for iBlock := 0 to Length(g1)-1 do
  2324. begin
  2325. setLength(blk, cwf[TCodeWordField.DataCodewordsInGroup1BlockCount]);
  2326. for i := 0 to cwf[TCodeWordField.DataCodewordsInGroup1BlockCount]-1 do
  2327. begin
  2328. cw := ReadCodeword(iPos);
  2329. blk[i] := cw;
  2330. end;
  2331. g1[iBlock] := blk;
  2332. end;
  2333. setLength(g2, cwf[TCodeWordField.BlocksInGroup2Count]);
  2334. for iBlock := 0 to Length(g2)-1 do
  2335. begin
  2336. setLength(blk, cwf[TCodeWordField.DataCodewordsInGroup2BlockCount]);
  2337. for i := 0 to cwf[TCodeWordField.DataCodewordsInGroup2BlockCount]-1 do
  2338. begin
  2339. cw := ReadCodeword(iPos);
  2340. blk[i] := cw;
  2341. end;
  2342. g2[iBlock] := blk;
  2343. end;
  2344. setLength(gECC1, length(g1));
  2345. for iBlock := 0 to length(g1)-1 do
  2346. begin
  2347. SetStatus('Calculating ECC Codewords Group 1 Block '+(iBlock+1).ToString);
  2348. blk := g1[iBlock];
  2349. inc(iECCSize, cwf[TCodeWordField.ECCodewordsPerBlock]);
  2350. rs := TReedSolomonGenerator.Create(cwf[TCodeWordField.ECCodewordsPerBlock]);
  2351. try
  2352. gECC1[iBlock] := rs.GetRemaineder(blk);
  2353. finally
  2354. rs.Free;
  2355. end;
  2356. end;
  2357. setLength(gECC2, length(g2));
  2358. for iBlock := 0 to length(g2)-1 do
  2359. begin
  2360. SetStatus('Calculating ECC Codewords Group 2 Block '+(iBlock+1).ToString);
  2361. blk := g2[iBlock];
  2362. inc(iECCSize, cwf[TCodeWordField.ECCodewordsPerBlock]);
  2363. rs := TReedSolomonGenerator.Create(cwf[TCodeWordField.ECCodewordsPerBlock]);
  2364. try
  2365. gECC2[iBlock] := rs.GetRemaineder(blk);
  2366. finally
  2367. rs.Free;
  2368. end;
  2369. end;
  2370. SetStatus('Interleaving Data Codewords');
  2371. SetLength(FCodeWords, CodewordCount+iECCSize);
  2372. iPos := 0;
  2373. iOutPos := 0;
  2374. repeat
  2375. if length(g1) > 0 then
  2376. begin
  2377. if iPos < cwf[TCodeWordField.DataCodewordsInGroup1BlockCount] then
  2378. for iBlock := 0 to length(g1)-1 do
  2379. begin
  2380. if iPos < length(g1[iBlock]) then
  2381. begin
  2382. FCodeWords[iOutPos] := g1[iBlock][iPos];
  2383. inc(iOutPos);
  2384. end;
  2385. end;
  2386. end;
  2387. if length(g2) > 0 then
  2388. begin
  2389. if iPos < cwf[TCodeWordField.DataCodewordsInGroup2BlockCount] then
  2390. for iBlock := 0 to length(g2)-1 do
  2391. begin
  2392. if iPos < length(g2[iBlock]) then
  2393. begin
  2394. FCodeWords[iOutPos] := g2[iBlock][iPos];
  2395. inc(iOutPos);
  2396. end;
  2397. end;
  2398. end;
  2399. inc(iPos);
  2400. until iOutPos >= (Length(FCodeWords)-iECCSize);
  2401. SetStatus('Interleaving ECC Codewords');
  2402. iPos := 0;
  2403. repeat
  2404. if length(gECC1) > 0 then
  2405. begin
  2406. if iPos < cwf[TCodeWordField.ECCodewordsPerBlock] then
  2407. for iBlock := 0 to length(gECC1)-1 do
  2408. begin
  2409. if iPos < length(gECC1[iBlock]) then
  2410. begin
  2411. FCodeWords[iOutPos] := gECC1[iBlock][iPos];
  2412. inc(iOutPos);
  2413. end;
  2414. end;
  2415. end;
  2416. if length(gECC2) > 0 then
  2417. begin
  2418. if iPos < cwf[TCodeWordField.ECCodewordsPerBlock] then
  2419. for iBlock := 0 to length(gECC2)-1 do
  2420. begin
  2421. if iPos < length(gECC2[iBlock]) then
  2422. begin
  2423. FCodeWords[iOutPos] := gECC2[iBlock][iPos];
  2424. inc(iOutPos);
  2425. end;
  2426. end;
  2427. end;
  2428. inc(iPos);
  2429. until iOutPos >= Length(FCodeWords);
  2430. FDataBits := OutputAsString;
  2431. for i := 1 to RemainderBits[FVersionInUse] do
  2432. begin
  2433. FDataBits := FDataBits + '0';
  2434. end;
  2435. SetStatus('Drawing Modules');
  2436. DrawModules;
  2437. end;
  2438. function TQRCode.GetText: string;
  2439. begin
  2440. Result := TEncoding.UTF8.GetString(FData);
  2441. end;
  2442. function TQRCode.MaxECL: TErrorCorrectionLevel;
  2443. begin
  2444. if Length(FData) < FVerCapacities[FVersionInUse].High[FMode] then
  2445. Exit(TErrorCorrectionLevel.High)
  2446. else if Length(FData) < FVerCapacities[FVersionInUse].Quartile[FMode] then
  2447. Exit(TErrorCorrectionLevel.Quartile)
  2448. else if Length(FData) < FVerCapacities[FVersionInUse].Medium[FMode] then
  2449. Exit(TErrorCorrectionLevel.Medium)
  2450. else if length(FData) < FVerCapacities[FVersionInUse].Low[FMode] then
  2451. Exit(TErrorCorrectionLevel.Low)
  2452. else
  2453. raise Exception.Create('The data supplied will not fit in the requested qr version.');
  2454. end;
  2455. function TQRCode.MinVersion : TVersion;
  2456. var
  2457. iLen : integer;
  2458. i : TVersion;
  2459. s : string;
  2460. begin
  2461. s := TEncoding.UTF8.GetString(FData);
  2462. iLen := Length(S);
  2463. for i := TVersion.v1 to TVersion.v40 do
  2464. begin
  2465. Result := i;
  2466. case FECLInUse of
  2467. TErrorCorrectionLevel.Low:
  2468. if iLen <= FVerCapacities[i].Low[Mode] then
  2469. break;
  2470. TErrorCorrectionLevel.Medium:
  2471. if iLen <= FVerCapacities[i].Medium[Mode] then
  2472. break;
  2473. TErrorCorrectionLevel.Quartile:
  2474. if iLen <= FVerCapacities[i].Quartile[Mode] then
  2475. break;
  2476. TErrorCorrectionLevel.High:
  2477. if iLen <= FVerCapacities[i].High[Mode] then
  2478. break;
  2479. end;
  2480. end;
  2481. end;
  2482. function TQRCode.OutputAsString: string;
  2483. var
  2484. i: Integer;
  2485. begin
  2486. Result := '';
  2487. for i := 0 to Length(FCodeWords)-1 do
  2488. begin
  2489. Result := Result+DecimalToBinary(FCodeWords[i],8);
  2490. end;
  2491. end;
  2492. procedure TQRCode.PaintQRCode;
  2493. var
  2494. x, y, width : integer;
  2495. Offset : integer;
  2496. FilledRects : TArray<TRect>;
  2497. iCnt : integer;
  2498. begin
  2499. if not Assigned(FOnPaint) then
  2500. exit;
  2501. width := (Length(FModules) * FPixelsPerModule) + (8 * FPixelsPerModule) + 2;
  2502. Offset := (4 * FPixelsPerModule)+1; // Quiet Zone
  2503. x := 0;
  2504. y := 0;
  2505. iCnt := 0;
  2506. setLength(FilledRects, Size * Size);
  2507. repeat
  2508. repeat
  2509. if FModules[x][y] then
  2510. begin
  2511. FilledRects[iCnt] :=
  2512. TRect.Create(
  2513. (x*FPixelsPerModule)+Offset,
  2514. (y*FPixelsPerModule)+Offset,
  2515. (x*FPixelsPerModule)+FPixelsPerModule+Offset,
  2516. (y*FPixelsPerModule)+FPixelsPerModule+Offset
  2517. );
  2518. inc(iCnt);
  2519. end;
  2520. inc(y);
  2521. until y = Length(FModules[x]);
  2522. y := 0;
  2523. inc(x);
  2524. until x = Length(FModules);
  2525. SetLength(FilledRects, iCnt);
  2526. FOnPaint(width, width, FilledRects);
  2527. end;
  2528. function TQRCode.Pow(i, k: Integer): Integer;
  2529. var
  2530. j, Count: Integer;
  2531. begin
  2532. if k>0 then j:=2
  2533. else j:=1;
  2534. for Count:=1 to k-1 do
  2535. j:=j*i;
  2536. Result:=j;
  2537. end;
  2538. function TQRCode.GetSize: integer;
  2539. begin
  2540. Result := (((Integer(FVersionInUse)-1)*4)+21);
  2541. end;
  2542. function TQRCode.ReadCodeword(var Pos: integer): Byte;
  2543. var
  2544. s : string;
  2545. iCnt : integer;
  2546. begin
  2547. iCnt := 0;
  2548. s := '';
  2549. repeat
  2550. if FBits[Pos] then
  2551. s := s+'1'
  2552. else
  2553. s := s+'0';
  2554. inc(iCnt);
  2555. inc(Pos);
  2556. until (Pos > FBitsPos) or (iCnt >= 8);
  2557. Result := BinaryToDecimal(s);
  2558. end;
  2559. procedure TQRCode.Redraw;
  2560. begin
  2561. UpdateCode;
  2562. end;
  2563. procedure TQRCode.SetData(const Value: TArray<Byte>);
  2564. begin
  2565. FData := Value;
  2566. UpdateCode;
  2567. end;
  2568. procedure TQRCode.SetECL(const Value: TErrorCorrectionLevel);
  2569. begin
  2570. FECL := Value;
  2571. if FECL <> TErrorCorrectionLevel.Auto then
  2572. FECLInUse := Value;
  2573. UpdateCode;
  2574. end;
  2575. procedure TQRCode.SetMask(const Value: TMask);
  2576. begin
  2577. FMask := Value;
  2578. UpdateCode;
  2579. end;
  2580. procedure TQRCode.SetOnPaint(const Value: TPaintHandler);
  2581. begin
  2582. FOnPaint := Value;
  2583. UpdateCode;
  2584. end;
  2585. procedure TQRCode.SetPixelsPerModule(const Value: integer);
  2586. begin
  2587. if Value <= 0 then
  2588. raise Exception.Create('PixelsPerModule cannot be sero or less.');
  2589. FPixelsPerModule := Value;
  2590. FRenderSize := FPixelsPerModule * Size;
  2591. UpdateCode;
  2592. end;
  2593. procedure TQRCode.SetRenderSize(const Value: integer);
  2594. begin
  2595. PixelsPerModule := Value div (Size+8);
  2596. end;
  2597. procedure TQRCode.SetStatus(const Msg: string);
  2598. begin
  2599. if Assigned(FOnStatus) then
  2600. FOnStatus(Msg);
  2601. end;
  2602. procedure TQRCode.SetText(const Value: string);
  2603. begin
  2604. FData := TEncoding.UTF8.GetBytes(Value);
  2605. UpdateCode;
  2606. end;
  2607. procedure TQRCode.SetVersion(const Value: TVersion);
  2608. begin
  2609. FVersion := Value;
  2610. if FVersion <> TVersion.Auto then
  2611. FVersionInUse := Value;
  2612. UpdateCode;
  2613. end;
  2614. procedure TQRCode.UpdateCode;
  2615. var
  2616. iReqBits : integer;
  2617. i: Integer;
  2618. begin
  2619. if FUpdateDepth > 0 then
  2620. exit;
  2621. SetLength(FBits, 0);
  2622. SetLength(FBits, 4096);
  2623. FBitsLen := 4096;
  2624. FBitsPos := 0;
  2625. FReservedAreas.Clear;
  2626. FMode := DetermineQRMode;
  2627. if FVersion = TVersion.Auto then
  2628. FVersionInUse := MinVersion
  2629. else
  2630. while (FVersionInUse < MinVersion) do
  2631. if (FECLInUse > TErrorCorrectionLevel.Low) and (FECL = TErrorCorrectionLevel.Auto) then
  2632. begin
  2633. Dec(FECLInUse);
  2634. end else
  2635. raise EQREncodeException.Create('Specified Version is too low for size of data to encode.');
  2636. if FECL = TErrorCorrectionLevel.Auto then
  2637. FECLInUse := MaxECL
  2638. else
  2639. while FECL > MaxECL do
  2640. begin
  2641. if (FVersionInUse < TVersion.v40) and (FVersion = TVersion.Auto) then
  2642. inc(FVersionInUse)
  2643. else
  2644. raise EQREncodeException.Create('Specified Error Correction Level is too high for this qr code version and data size.');
  2645. end;
  2646. SetStatus('Initializing Bits');
  2647. WriteMode;
  2648. WriteLength;
  2649. SetStatus('Encoding Data');
  2650. case FMode of
  2651. TQRMode.Numeric:
  2652. EncodeNumeric;
  2653. TQRMode.AlphaNumeric:
  2654. EncodeAlphaNumeric;
  2655. TQRMode.Byte:
  2656. EncodeByte;
  2657. TQRMode.Kanji:
  2658. EncodeKanji;
  2659. end;
  2660. iReqBits := DataCodewordCount * 8;
  2661. for i := 1 to 4 do
  2662. begin
  2663. if FBitsPos < iReqBits then
  2664. WriteBit(False);
  2665. end;
  2666. while (FBitsPos mod 8) <> 0 do
  2667. WriteBit(False);
  2668. while FBitsPos < iReqBits do
  2669. begin
  2670. WriteBits('11101100');
  2671. if FBitsPos < iReqBits then
  2672. WriteBits('00010001');
  2673. end;
  2674. SetStatus('Calculating Modules');
  2675. CalculateModules;
  2676. SetStatus('Painting Code');
  2677. PaintQRCode;
  2678. end;
  2679. procedure TQRCode.WriteBit(b: boolean);
  2680. begin
  2681. FBits[FBitsPos] := b ;
  2682. inc(FBitsPos);
  2683. CheckBitsPos;
  2684. end;
  2685. procedure TQRCode.WriteBits(const s: string);
  2686. var
  2687. c: Char;
  2688. begin
  2689. for c in s do
  2690. begin
  2691. if c = '0' then
  2692. WriteBit(False)
  2693. else if c = '1' then
  2694. WriteBit(True)
  2695. else
  2696. raise Exception.Create('Bad Bit');
  2697. end;
  2698. end;
  2699. procedure TQRCode.WriteLength;
  2700. var
  2701. s : string;
  2702. iBits : integer;
  2703. begin
  2704. case FVersionInUse of
  2705. TVersion.v1..TVersion.v9:
  2706. case FMode of
  2707. TQRMode.Numeric:
  2708. iBits := 10;
  2709. TQRMode.AlphaNumeric:
  2710. iBits := 9;
  2711. TQRMode.Byte:
  2712. iBits := 8;
  2713. TQRMode.Kanji:
  2714. iBits := 8;
  2715. else
  2716. iBits := 0;
  2717. end;
  2718. TVersion.v10..TVersion.v26:
  2719. case FMode of
  2720. TQRMode.Numeric:
  2721. iBits := 12;
  2722. TQRMode.AlphaNumeric:
  2723. iBits := 11;
  2724. TQRMode.Byte:
  2725. iBits := 16;
  2726. TQRMode.Kanji:
  2727. iBits := 10;
  2728. else
  2729. iBits := 0;
  2730. end;
  2731. TVersion.v27..TVersion.v40:
  2732. case FMode of
  2733. TQRMode.Numeric:
  2734. iBits := 14;
  2735. TQRMode.AlphaNumeric:
  2736. iBits := 13;
  2737. TQRMode.Byte:
  2738. iBits := 16;
  2739. TQRMode.Kanji:
  2740. iBits := 12;
  2741. else
  2742. iBits := 0;
  2743. end;
  2744. else
  2745. iBits := 0;
  2746. end;
  2747. s := DecimalToBinary(length(FData), iBits);
  2748. while length(s) < iBits do
  2749. s := '0'+s;
  2750. WriteBits(s);
  2751. end;
  2752. procedure TQRCode.WriteMode;
  2753. begin
  2754. case FMode of
  2755. TQRMode.Numeric:
  2756. WriteBits('0001');
  2757. TQRMode.AlphaNumeric:
  2758. WriteBits('0010');
  2759. TQRMode.Byte:
  2760. WriteBits('0100');
  2761. TQRMode.Kanji:
  2762. WriteBits('1000');
  2763. end;
  2764. end;
  2765. { TQRCode.TArrayHelper<T> }
  2766. class function TQRCode.TArrayHelper<T>.AdvanceArray(Source: TArray<T>;
  2767. idx: integer): TArray<T>;
  2768. var
  2769. i: Integer;
  2770. begin
  2771. SetLength(Result,Length(Source)-idx);
  2772. for i := 0 to Length(Result)-1 do
  2773. Result[i] := Source[i+idx];
  2774. end;
  2775. class function TQRCode.TArrayHelper<T>.Combination(SourceArray: TArray<T>;
  2776. SubsetSize: Cardinal): TArray<TArray<T>>;
  2777. var
  2778. i, iResultSize, iNum, iDenom : Cardinal;
  2779. idx: Cardinal;
  2780. ary : TArray<T>;
  2781. begin
  2782. iNum := 1;
  2783. iDenom := 1;
  2784. for i := Length(SourceArray) downto Length(SourceArray)-SubsetSize+1 do
  2785. iNum := iNum*i;
  2786. for i := SubsetSize downto 1 do
  2787. iDenom := iDenom*i;
  2788. iResultSize := iNum div iDenom;
  2789. SetLength(Result, iResultSize);
  2790. SetLength(ary,0);
  2791. idx := 0;
  2792. NextCombo(ary, SourceArray, SubsetSize, Result, idx);
  2793. end;
  2794. class procedure TQRCode.TArrayHelper<T>.NextCombo(Prefix, Source: TArray<T>;
  2795. Count: Cardinal; Result: TArray<TArray<T>>; var ResultIdx: Cardinal);
  2796. var
  2797. i : integer;
  2798. a: T;
  2799. ary : TArray<T>;
  2800. begin
  2801. if Count = 0 then
  2802. begin
  2803. Result[ResultIdx] := Prefix;
  2804. inc(ResultIdx);
  2805. exit;
  2806. end;
  2807. for i := 0 to length(Source)-1 do
  2808. begin
  2809. a := Source[i];
  2810. ary := Prefix;
  2811. SetLength(ary,Length(ary)+1);
  2812. ary[Length(ary)-1] := a;
  2813. NextCombo(ary, AdvanceArray(Source,i+1), Count-1,Result,ResultIdx);
  2814. end;
  2815. end;
  2816. { TQRCode.TRectHelper }
  2817. function TQRCode.TRectHelper.IntersectsWithPoint(const pt: TPoint): boolean;
  2818. begin
  2819. Result := IntersectsWithRect(TRect.Create(pt.X, pt.Y, pt.X, pt.Y));
  2820. end;
  2821. function TQRCode.TRectHelper.IntersectsWithRect(const R: TRect): boolean;
  2822. begin
  2823. Result := (Self.Left <= R.Right)
  2824. and (Self.Right >= R.Left)
  2825. and (Self.Top <= R.Bottom)
  2826. and (Self.Bottom >= R.Top);
  2827. end;
  2828. end.