├── preview.jpg
├── BMP2JPG
├── 02 - plsql function.sql
├── example.sql
└── 01 - bmp2jpg java.sql
├── LICENSE
├── apexplugin.json
├── README.md
├── plugin
├── item_type_plugin_eu_zttech_qr_code.sql
└── olderversions
│ └── item_type_plugin_eu_zttech_qr_code_func_api.sql
└── package
├── ZT_QR.pks
└── ZT_QR.pkb
/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zorantica/plsql-qr-code/HEAD/preview.jpg
--------------------------------------------------------------------------------
/BMP2JPG/02 - plsql function.sql:
--------------------------------------------------------------------------------
1 | CREATE OR REPLACE FUNCTION f_bmp2jpg(p_bmp_image blob) RETURN blob AS
2 | language java name 'Bmp2JPG.convert2JPG(oracle.sql.BLOB) return oracle.sql.BLOB'
3 | ;
4 |
--------------------------------------------------------------------------------
/BMP2JPG/example.sql:
--------------------------------------------------------------------------------
1 | DECLARE
2 | lbQR blob;
3 |
4 | BEGIN
5 | lbQR := f_bmp2jpg(
6 | ZT_QR.F_QR_AS_BMP(
7 | p_data => 'HTTP://WWW.ZT-TECH.EU',
8 | p_error_correction => 'M')
9 | );
10 |
11 | ZT_QR.p_save_file(lbQR, 'qr.jpg', 'E_SHARED');
12 | END;
13 |
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2018 - Zoran Tica
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
11 | all 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
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/apexplugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "QRCode",
3 | "version" : "1.0.0",
4 | "description" : "QRCode is an item type plugin that provides functionality to show QR Code for desired input value. QR Code can be rendered as HTML table or BMP image.",
5 | "keywords" : ["qr code"],
6 | "homepage" : "https://github.com/zorantica/plsql-qr-code",
7 | "bugs" : {
8 | "url" : "https://github.com/zorantica/plsql-qr-code/issues",
9 | "email" : "zoran.tica@gmail.com"
10 | },
11 | "license" : "MIT",
12 | "author" : {
13 | "name" : "Zoran Tica",
14 | "email" : "zoran.tica@gmail.com",
15 | "url" : "http://www.zt-tech.eu",
16 | "twitter" : "zoran_tica"
17 | },
18 | "repository" : {
19 | "type" : "git",
20 | "url" : "https://github.com/zorantica/plsql-qr-code.git"
21 | },
22 | "oracle" : {
23 | "versions" : ["11.2.0.1", "12.1.0.1", "12.2.0.1", "18.0.0.0.0 >=" ],
24 | "apex" : {
25 | "versions" : ["5.0.0 >="],
26 | "plugin" : {
27 | "internalName" : "EU.ZTTECH.QRCODE",
28 | "type" : "item",
29 | "demo" : "https://apex.oracle.com/pls/apex/f?p=zttechdemo",
30 | "previewImage" : "https://raw.githubusercontent.com/zorantica/plsql-qr-code/master/preview.jpg"
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/BMP2JPG/01 - bmp2jpg java.sql:
--------------------------------------------------------------------------------
1 | create or replace and compile java source named Bmp2Jpeg
2 | as
3 |
4 | import oracle.sql.BLOB;
5 | import oracle.sql.*;
6 | import oracle.jdbc.driver.*;
7 | import java.sql.*;
8 | import javax.imageio.ImageIO;
9 | import java.awt.image.BufferedImage;
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.File;
12 | import java.io.FileOutputStream;
13 | import java.io.OutputStream;
14 | import java.io.*;
15 | import java.util.*;
16 | import javax.imageio.ImageIO;
17 | import java.awt.image.BufferedImage;
18 | import java.sql.Blob;
19 |
20 | public class Bmp2JPG {
21 |
22 | static OracleDriver ora = new OracleDriver();
23 | static Connection conn;
24 | static ByteArrayOutputStream out;
25 | static {
26 | try {
27 | conn = ora.defaultConnection();
28 | } catch (Exception ex) {}
29 | }
30 | public static ByteArrayOutputStream TO_JPG(java.sql.Blob blob) throws Exception {
31 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
32 | BufferedImage image = ImageIO.read(blob.getBinaryStream());
33 | ImageIO.write(image, "jpeg", outputStream);
34 |
35 |
36 | return outputStream;
37 | }
38 |
39 | public static oracle.sql.BLOB convert2JPG(oracle.sql.BLOB value) throws Exception {
40 |
41 | if (conn == null) conn = ora.defaultConnection();
42 | BLOB retBlob = BLOB.createTemporary(conn, true, oracle.sql.BLOB.DURATION_SESSION);
43 |
44 | ByteArrayOutputStream out = new ByteArrayOutputStream();
45 | out = Bmp2JPG.TO_JPG(value);
46 |
47 | try {
48 | java.io.OutputStream outStr = retBlob.setBinaryStream(0);
49 | outStr.write(out.toByteArray());
50 | outStr.flush();
51 | } finally {
52 | out.close();
53 | }
54 | return retBlob;
55 | }
56 | }
57 |
58 |
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Oracle PL/SQL Package and APEX plugin for QR Code Generation
2 | QR Codes Generator package provides functionality to quickly and efficiently generate QR Codes (module 2) directly from Oracle database.
3 |
4 | It requires no additional resources and it is developed in pure PL/SQL.
5 |
6 | Item-type APEX plugin uses PL/SQL package for calculations and graphical implementation of QR code and simplifies QR code usage in APEX applications.
7 |
8 | ## Changelog
9 | - 1.0 - Initial Release
10 | - 1.1 - Added APEX plugin
11 | - 1.2 - UTF-8 support
12 | - 1.3 - "_" and "%" BUG resolved (Franz.Apeltauer@prinzhorn-holding.com, thank You for kind help!)
13 | - 1.4 - added function f_qr_as_long_raw
14 | - 1.5 - terminator zeroes BUG solved (Markus Lobedann, thank You for kind help!)
15 | - 1.6 - older databases compatilbility (10g)
16 | - 1.7 - Numeric mode BUG with "0" at the beginning of triplet group
17 | - 2.0 - SVG image files support
18 | - 2.1 - Show logo in QR code
19 | - 2.2 - Select a QR code and background color for BMP representation (thank You k0mita for the contribution!)
20 |
21 | ## Install PL/SQL package
22 | - download 2 script files from "package" directory
23 | - execute them in database schema in following order:
24 | 1. PKS script file (package definition)
25 | 2. PKB file (package body)
26 |
27 | New Package ZT_QR is created in database schema.
28 |
29 | ## How to use PL/SQL package
30 | Procedure and Function descriptions with input and output parameters and examples are located in package definition script.
31 |
32 | ## Use JPG images instead of BMP
33 | BI Publisher (and potentialy some other software) is not displaying QR code BMP images correctly.
34 |
35 | Solution is to convert BMP images to JPG using JAVA in database - thanks to mr Hamzeh Fathi (hfathi54@gmail.com).
36 |
37 | How to install and use this functionality:
38 | - download 2 script files from "BMP2JPG" directory
39 | - install JAVA source from file "01 - bmp2jpg java.sql"
40 | - install PL/SQL function wrapper for JAVA source from file "02 - plsql function.sql"; function can be installed as standalone or in some package (for example in QR code package)
41 |
42 | That's it. Usage example for standalone function can be found in file "example.sql".
43 |
44 | Remark: this way images also get smaller in size.
45 |
46 | ## Install APEX plugin
47 | - First install PL/SQL package from "package" directory
48 | - Then import plugin file "item_type_plugin_eu_zttech_qr_code.sql" from "apex plugin" directory into your application
49 |
50 | For older versions of APEX, which use deprecated "Function" API interface use plugin file "item_type_plugin_eu_zttech_qr_code_func_api.sql" from "apex plugin/older versions" directory.
51 |
52 | ## Plugin Settings
53 | For calculation and graphic representation of QR Code there are following parameters:
54 | - Error correction level (4 different levels used for QR Code calculation)
55 | - Margines (Yes/No - show 4 modules margine around QR Code or not)
56 | - Display type (SVG image (default), HTML table or BMP image)
57 | - Module size (used when "HTML table" or "SVG image" display type is selected - defines moduze size in pixels)
58 | - Image size (used when "BMP image" display type is selected - defines image size in pixels)
59 | - Module color (used when "SVG image" display type is selected - defines module color; colors can be defined as named colors (for example black, red, white...), using rgb function (for example rgb(255, 0, 0) ) or HEX values (for example #FF0000) )
60 | - Background color (used when "SVG image" display type is selected - defines QR code background color; colors can be defined as named colors (for example black, red, white...), using rgb function (for example rgb(255, 0, 0) ) or HEX values (for example #FF0000) )
61 | - Rounded module edges (used when "SVG image" display type is selected - defines if modules should have rounded edges; if size of this parameter is half the module size (or larger) then modules are represented as circles)
62 |
63 | ## Demo Application
64 | https://apex.oracle.com/pls/apex/f?p=zttechdemo
65 |
66 | 
67 |
--------------------------------------------------------------------------------
/plugin/item_type_plugin_eu_zttech_qr_code.sql:
--------------------------------------------------------------------------------
1 | prompt --application/set_environment
2 | set define off verify off feedback off
3 | whenever sqlerror exit sql.sqlcode rollback
4 | --------------------------------------------------------------------------------
5 | --
6 | -- ORACLE Application Express (APEX) export file
7 | --
8 | -- You should run the script connected to SQL*Plus as the Oracle user
9 | -- APEX_190100 or as the owner (parsing schema) of the application.
10 | --
11 | -- NOTE: Calls to apex_application_install override the defaults below.
12 | --
13 | --------------------------------------------------------------------------------
14 | begin
15 | wwv_flow_api.import_begin (
16 | p_version_yyyy_mm_dd=>'2018.04.04'
17 | ,p_release=>'18.1.0.00.45'
18 | ,p_default_workspace_id=>1622468447055903
19 | ,p_default_application_id=>102
20 | ,p_default_owner=>'TICA'
21 | );
22 | end;
23 | /
24 | prompt --application/shared_components/plugins/item_type/eu_zttech_qrcode
25 | begin
26 | wwv_flow_api.create_plugin(
27 | p_id=>wwv_flow_api.id(19166686046667066)
28 | ,p_plugin_type=>'ITEM TYPE'
29 | ,p_name=>'EU.ZTTECH.QRCODE'
30 | ,p_display_name=>'QR Code'
31 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
32 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
33 | ,p_plsql_code=>wwv_flow_string.join(wwv_flow_t_varchar2(
34 | 'PROCEDURE render_qrcode(',
35 | ' p_item IN apex_plugin.t_item,',
36 | ' p_plugin IN apex_plugin.t_plugin,',
37 | ' p_param IN apex_plugin.t_item_render_param,',
38 | ' p_result OUT apex_plugin.t_item_render_result) IS',
39 | ' ',
40 | 'BEGIN',
41 | ' if p_param.value is null then',
42 | ' htp.p(''no data'');',
43 | ' else',
44 | '',
45 | ' -- Printer Friendly Display',
46 | ' IF p_param.is_printer_friendly THEN',
47 | ' apex_plugin_util.print_display_only(p_item_name => p_item.name,',
48 | ' p_display_value => p_param.value,',
49 | ' p_show_line_breaks => FALSE,',
50 | ' p_escape => TRUE,',
51 | ' p_attributes => p_item.element_attributes);',
52 | ' -- Read Only Display',
53 | ' ELSIF p_param.is_readonly THEN',
54 | ' apex_plugin_util.print_hidden_if_readonly(p_item_name => p_item.name,',
55 | ' p_value => p_param.value,',
56 | ' p_is_readonly => p_param.is_readonly,',
57 | ' p_is_printer_friendly => p_param.is_printer_friendly);',
58 | '',
59 | ' -- Normal Display',
60 | ' ELSE',
61 | ' if p_item.attribute_02 = ''HTML'' then',
62 | ' ZT_QR.p_qr_as_html_table(',
63 | ' p_data => p_param.value,',
64 | ' p_error_correction => p_item.attribute_01,',
65 | ' p_module_size_in_px => p_item.attribute_03,',
66 | ' p_margines => (CASE WHEN p_item.attribute_05 = ''Y'' THEN true ELSE false END)',
67 | ' );',
68 | ' elsif p_item.attribute_02 = ''BMP'' then',
69 | ' ZT_QR.p_qr_as_img_tag_base64(',
70 | ' p_data => p_param.value,',
71 | ' p_error_correction => p_item.attribute_01,',
72 | ' p_image_size_px => p_item.attribute_04,',
73 | ' p_margines => p_item.attribute_05',
74 | ' );',
75 | ' elsif p_item.attribute_02 = ''SVG'' then',
76 | ' ZT_QR.p_qr_as_svg(',
77 | ' p_data => p_param.value,',
78 | ' p_error_correction => p_item.attribute_01,',
79 | ' p_module_size_px => p_item.attribute_03,',
80 | ' p_margines_yn => p_item.attribute_05,',
81 | ' p_module_color => p_item.attribute_06,',
82 | ' p_background_color => p_item.attribute_07,',
83 | ' p_module_rounded_px => p_item.attribute_08',
84 | ' );',
85 | ' ',
86 | ' --htp.p(''
Download'');',
87 | ' else',
88 | ' htp.prn(''Error - unsupported display type.'');',
89 | ' end if;',
90 | ' ',
91 | ' end if;',
92 | ' ',
93 | ' end if;',
94 | '',
95 | ' p_result.is_navigable := false;',
96 | ' ',
97 | 'END render_qrcode;'))
98 | ,p_api_version=>2
99 | ,p_render_function=>'render_qrcode'
100 | ,p_standard_attributes=>'VISIBLE:FORM_ELEMENT:SESSION_STATE:SOURCE'
101 | ,p_substitute_attributes=>true
102 | ,p_subscribe_plugin_settings=>true
103 | ,p_help_text=>wwv_flow_string.join(wwv_flow_t_varchar2(
104 | 'QR plugin version 2.0.0',
105 | 'Usage and details on GitHub',
106 | 'https://github.com/zorantica/plsql-qr-code'))
107 | ,p_version_identifier=>'2.0.0.0'
108 | ,p_about_url=>'https://github.com/zorantica/plsql-qr-code'
109 | );
110 | wwv_flow_api.create_plugin_attribute(
111 | p_id=>wwv_flow_api.id(19195010070495085)
112 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
113 | ,p_attribute_scope=>'COMPONENT'
114 | ,p_attribute_sequence=>1
115 | ,p_display_sequence=>10
116 | ,p_prompt=>'Error correction level'
117 | ,p_attribute_type=>'SELECT LIST'
118 | ,p_is_required=>true
119 | ,p_default_value=>'L'
120 | ,p_supported_ui_types=>'DESKTOP'
121 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS:APEX_APPL_PAGE_IG_COLUMNS'
122 | ,p_is_translatable=>false
123 | ,p_lov_type=>'STATIC'
124 | );
125 | wwv_flow_api.create_plugin_attr_value(
126 | p_id=>wwv_flow_api.id(19195587333496851)
127 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
128 | ,p_display_sequence=>10
129 | ,p_display_value=>'L - Low (7% of data)'
130 | ,p_return_value=>'L'
131 | );
132 | wwv_flow_api.create_plugin_attr_value(
133 | p_id=>wwv_flow_api.id(19195953361499270)
134 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
135 | ,p_display_sequence=>20
136 | ,p_display_value=>'M - Medium (15% of data)'
137 | ,p_return_value=>'M'
138 | );
139 | wwv_flow_api.create_plugin_attr_value(
140 | p_id=>wwv_flow_api.id(19196401846501124)
141 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
142 | ,p_display_sequence=>30
143 | ,p_display_value=>'Q - Quartile (25% of data)'
144 | ,p_return_value=>'Q'
145 | );
146 | wwv_flow_api.create_plugin_attr_value(
147 | p_id=>wwv_flow_api.id(19196767711502010)
148 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
149 | ,p_display_sequence=>40
150 | ,p_display_value=>'H - High (30% of data)'
151 | ,p_return_value=>'H'
152 | );
153 | wwv_flow_api.create_plugin_attribute(
154 | p_id=>wwv_flow_api.id(19203464560101742)
155 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
156 | ,p_attribute_scope=>'COMPONENT'
157 | ,p_attribute_sequence=>2
158 | ,p_display_sequence=>20
159 | ,p_prompt=>'Display Type'
160 | ,p_attribute_type=>'SELECT LIST'
161 | ,p_is_required=>true
162 | ,p_default_value=>'SVG'
163 | ,p_supported_ui_types=>'DESKTOP'
164 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS:APEX_APPL_PAGE_IG_COLUMNS'
165 | ,p_is_translatable=>false
166 | ,p_lov_type=>'STATIC'
167 | );
168 | wwv_flow_api.create_plugin_attr_value(
169 | p_id=>wwv_flow_api.id(15301637796637240)
170 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
171 | ,p_display_sequence=>5
172 | ,p_display_value=>'SVG image'
173 | ,p_return_value=>'SVG'
174 | );
175 | wwv_flow_api.create_plugin_attr_value(
176 | p_id=>wwv_flow_api.id(19204051603103163)
177 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
178 | ,p_display_sequence=>10
179 | ,p_display_value=>'HTML Table'
180 | ,p_return_value=>'HTML'
181 | );
182 | wwv_flow_api.create_plugin_attr_value(
183 | p_id=>wwv_flow_api.id(19204426782104803)
184 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
185 | ,p_display_sequence=>20
186 | ,p_display_value=>'BMP Image'
187 | ,p_return_value=>'BMP'
188 | );
189 | wwv_flow_api.create_plugin_attribute(
190 | p_id=>wwv_flow_api.id(19206265959135863)
191 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
192 | ,p_attribute_scope=>'COMPONENT'
193 | ,p_attribute_sequence=>3
194 | ,p_display_sequence=>30
195 | ,p_prompt=>'Module size'
196 | ,p_attribute_type=>'NUMBER'
197 | ,p_is_required=>true
198 | ,p_default_value=>'8'
199 | ,p_display_length=>5
200 | ,p_max_length=>2
201 | ,p_unit=>'pixels'
202 | ,p_supported_ui_types=>'DESKTOP'
203 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
204 | ,p_is_translatable=>false
205 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
206 | ,p_depending_on_has_to_exist=>true
207 | ,p_depending_on_condition_type=>'IN_LIST'
208 | ,p_depending_on_expression=>'HTML,SVG'
209 | );
210 | wwv_flow_api.create_plugin_attribute(
211 | p_id=>wwv_flow_api.id(19207654617152716)
212 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
213 | ,p_attribute_scope=>'COMPONENT'
214 | ,p_attribute_sequence=>4
215 | ,p_display_sequence=>40
216 | ,p_prompt=>'Image size'
217 | ,p_attribute_type=>'NUMBER'
218 | ,p_is_required=>true
219 | ,p_display_length=>5
220 | ,p_max_length=>4
221 | ,p_unit=>'pixels'
222 | ,p_is_translatable=>false
223 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
224 | ,p_depending_on_has_to_exist=>true
225 | ,p_depending_on_condition_type=>'EQUALS'
226 | ,p_depending_on_expression=>'BMP'
227 | );
228 | wwv_flow_api.create_plugin_attribute(
229 | p_id=>wwv_flow_api.id(19208230004156464)
230 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
231 | ,p_attribute_scope=>'COMPONENT'
232 | ,p_attribute_sequence=>5
233 | ,p_display_sequence=>15
234 | ,p_prompt=>'Margines'
235 | ,p_attribute_type=>'CHECKBOX'
236 | ,p_is_required=>true
237 | ,p_default_value=>'N'
238 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
239 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
240 | ,p_is_translatable=>false
241 | );
242 | wwv_flow_api.create_plugin_attribute(
243 | p_id=>wwv_flow_api.id(15310884392722565)
244 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
245 | ,p_attribute_scope=>'COMPONENT'
246 | ,p_attribute_sequence=>6
247 | ,p_display_sequence=>60
248 | ,p_prompt=>'Module color'
249 | ,p_attribute_type=>'TEXT'
250 | ,p_is_required=>false
251 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
252 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
253 | ,p_is_translatable=>false
254 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
255 | ,p_depending_on_has_to_exist=>true
256 | ,p_depending_on_condition_type=>'EQUALS'
257 | ,p_depending_on_expression=>'SVG'
258 | ,p_examples=>'black | red | rgb(255, 0, 0) | #FF0000'
259 | ,p_help_text=>'Module color (as named color, rgb function or HEX# notification).'
260 | );
261 | wwv_flow_api.create_plugin_attribute(
262 | p_id=>wwv_flow_api.id(15311493488724950)
263 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
264 | ,p_attribute_scope=>'COMPONENT'
265 | ,p_attribute_sequence=>7
266 | ,p_display_sequence=>70
267 | ,p_prompt=>'Background color'
268 | ,p_attribute_type=>'TEXT'
269 | ,p_is_required=>false
270 | ,p_is_translatable=>false
271 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
272 | ,p_depending_on_has_to_exist=>true
273 | ,p_depending_on_condition_type=>'EQUALS'
274 | ,p_depending_on_expression=>'SVG'
275 | );
276 | wwv_flow_api.create_plugin_attribute(
277 | p_id=>wwv_flow_api.id(15320807577751337)
278 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
279 | ,p_attribute_scope=>'COMPONENT'
280 | ,p_attribute_sequence=>8
281 | ,p_display_sequence=>80
282 | ,p_prompt=>'Rounded module edges'
283 | ,p_attribute_type=>'NUMBER'
284 | ,p_is_required=>false
285 | ,p_unit=>'pixel'
286 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
287 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
288 | ,p_is_translatable=>false
289 | );
290 | end;
291 | /
292 | begin
293 | wwv_flow_api.import_end(p_auto_install_sup_obj => nvl(wwv_flow_application_install.get_auto_install_sup_obj, false), p_is_component_import => true);
294 | commit;
295 | end;
296 | /
297 | set verify on feedback on define on
298 | prompt ...done
299 |
--------------------------------------------------------------------------------
/plugin/olderversions/item_type_plugin_eu_zttech_qr_code_func_api.sql:
--------------------------------------------------------------------------------
1 | prompt --application/set_environment
2 | set define off verify off feedback off
3 | whenever sqlerror exit sql.sqlcode rollback
4 | --------------------------------------------------------------------------------
5 | --
6 | -- ORACLE Application Express (APEX) export file
7 | --
8 | -- You should run the script connected to SQL*Plus as the Oracle user
9 | -- APEX_190100 or as the owner (parsing schema) of the application.
10 | --
11 | -- NOTE: Calls to apex_application_install override the defaults below.
12 | --
13 | --------------------------------------------------------------------------------
14 | begin
15 | wwv_flow_api.import_begin (
16 | p_version_yyyy_mm_dd=>'2016.08.24'
17 | ,p_release=>'5.1.1.00.08'
18 | ,p_default_workspace_id=>1962282725390507
19 | ,p_default_application_id=>1000
20 | ,p_default_owner=>'TICA'
21 | );
22 | end;
23 | /
24 | prompt --application/shared_components/plugins/item_type/eu_zttech_qrcode
25 | begin
26 | wwv_flow_api.create_plugin(
27 | p_id=>wwv_flow_api.id(19166686046667066)
28 | ,p_plugin_type=>'ITEM TYPE'
29 | ,p_name=>'EU.ZTTECH.QRCODE'
30 | ,p_display_name=>'QR Code'
31 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
32 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
33 | ,p_plsql_code=>wwv_flow_string.join(wwv_flow_t_varchar2(
34 | 'FUNCTION render_qrcode(p_item IN apex_plugin.t_page_item,',
35 | ' p_plugin IN apex_plugin.t_plugin,',
36 | ' p_value IN VARCHAR2,',
37 | ' p_is_readonly IN BOOLEAN,',
38 | ' p_is_printer_friendly IN BOOLEAN)',
39 | ' RETURN apex_plugin.t_page_item_render_result IS',
40 | '',
41 | ' l_result apex_plugin.t_page_item_render_result;',
42 | '',
43 | 'BEGIN',
44 | ' if p_value is null then',
45 | ' htp.p(''no data'');',
46 | ' else',
47 | '',
48 | ' -- Printer Friendly Display',
49 | ' IF p_is_printer_friendly THEN',
50 | ' apex_plugin_util.print_display_only(p_item_name => p_item.name,',
51 | ' p_display_value => p_value,',
52 | ' p_show_line_breaks => FALSE,',
53 | ' p_escape => TRUE,',
54 | ' p_attributes => p_item.element_attributes);',
55 | ' -- Read Only Display',
56 | ' ELSIF p_is_readonly THEN',
57 | ' apex_plugin_util.print_hidden_if_readonly(p_item_name => p_item.name,',
58 | ' p_value => p_value,',
59 | ' p_is_readonly => p_is_readonly,',
60 | ' p_is_printer_friendly => p_is_printer_friendly);',
61 | '',
62 | ' -- Normal Display',
63 | ' ELSE',
64 | ' if p_item.attribute_02 = ''HTML'' then',
65 | ' ZT_QR.p_qr_as_html_table(',
66 | ' p_data => p_value,',
67 | ' p_error_correction => p_item.attribute_01,',
68 | ' p_module_size_in_px => p_item.attribute_03,',
69 | ' p_margines => (CASE WHEN p_item.attribute_05 = ''Y'' THEN true ELSE false END)',
70 | ' );',
71 | ' elsif p_item.attribute_02 = ''BMP'' then',
72 | ' ZT_QR.p_qr_as_img_tag_base64(',
73 | ' p_data => p_value,',
74 | ' p_error_correction => p_item.attribute_01,',
75 | ' p_image_size_px => p_item.attribute_04,',
76 | ' p_margines => p_item.attribute_05',
77 | ' );',
78 | ' elsif p_item.attribute_02 = ''SVG'' then',
79 | ' ZT_QR.p_qr_as_svg(',
80 | ' p_data => p_value,',
81 | ' p_error_correction => p_item.attribute_01,',
82 | ' p_module_size_px => p_item.attribute_03,',
83 | ' p_margines_yn => p_item.attribute_05,',
84 | ' p_module_color => p_item.attribute_06,',
85 | ' p_background_color => p_item.attribute_07,',
86 | ' p_module_rounded_px => p_item.attribute_08',
87 | ' );',
88 | ' ',
89 | ' --htp.p(''
Download'');',
90 | ' else',
91 | ' htp.prn(''Error - unsupported display type.'');',
92 | ' end if;',
93 | ' end if;',
94 | ' ',
95 | ' end if;',
96 | '',
97 | ' l_result.is_navigable := false;',
98 | ' RETURN l_result;',
99 | '',
100 | 'END render_qrcode;'))
101 | ,p_api_version=>2
102 | ,p_render_function=>'render_qrcode'
103 | ,p_standard_attributes=>'VISIBLE:FORM_ELEMENT:SESSION_STATE:SOURCE'
104 | ,p_substitute_attributes=>true
105 | ,p_subscribe_plugin_settings=>true
106 | ,p_help_text=>wwv_flow_string.join(wwv_flow_t_varchar2(
107 | 'QR plugin version 2.0.0',
108 | 'Usage and details on GitHub',
109 | 'https://github.com/zorantica/plsql-qr-code'))
110 | ,p_version_identifier=>'2.0.0.0'
111 | ,p_about_url=>'https://github.com/zorantica/plsql-qr-code'
112 | );
113 | wwv_flow_api.create_plugin_attribute(
114 | p_id=>wwv_flow_api.id(19195010070495085)
115 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
116 | ,p_attribute_scope=>'COMPONENT'
117 | ,p_attribute_sequence=>1
118 | ,p_display_sequence=>10
119 | ,p_prompt=>'Error correction level'
120 | ,p_attribute_type=>'SELECT LIST'
121 | ,p_is_required=>true
122 | ,p_default_value=>'L'
123 | ,p_supported_ui_types=>'DESKTOP'
124 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS:APEX_APPL_PAGE_IG_COLUMNS'
125 | ,p_is_translatable=>false
126 | ,p_lov_type=>'STATIC'
127 | );
128 | wwv_flow_api.create_plugin_attr_value(
129 | p_id=>wwv_flow_api.id(19195587333496851)
130 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
131 | ,p_display_sequence=>10
132 | ,p_display_value=>'L - Low (7% of data)'
133 | ,p_return_value=>'L'
134 | );
135 | wwv_flow_api.create_plugin_attr_value(
136 | p_id=>wwv_flow_api.id(19195953361499270)
137 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
138 | ,p_display_sequence=>20
139 | ,p_display_value=>'M - Medium (15% of data)'
140 | ,p_return_value=>'M'
141 | );
142 | wwv_flow_api.create_plugin_attr_value(
143 | p_id=>wwv_flow_api.id(19196401846501124)
144 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
145 | ,p_display_sequence=>30
146 | ,p_display_value=>'Q - Quartile (25% of data)'
147 | ,p_return_value=>'Q'
148 | );
149 | wwv_flow_api.create_plugin_attr_value(
150 | p_id=>wwv_flow_api.id(19196767711502010)
151 | ,p_plugin_attribute_id=>wwv_flow_api.id(19195010070495085)
152 | ,p_display_sequence=>40
153 | ,p_display_value=>'H - High (30% of data)'
154 | ,p_return_value=>'H'
155 | );
156 | wwv_flow_api.create_plugin_attribute(
157 | p_id=>wwv_flow_api.id(19203464560101742)
158 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
159 | ,p_attribute_scope=>'COMPONENT'
160 | ,p_attribute_sequence=>2
161 | ,p_display_sequence=>20
162 | ,p_prompt=>'Display Type'
163 | ,p_attribute_type=>'SELECT LIST'
164 | ,p_is_required=>true
165 | ,p_default_value=>'SVG'
166 | ,p_supported_ui_types=>'DESKTOP'
167 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS:APEX_APPL_PAGE_IG_COLUMNS'
168 | ,p_is_translatable=>false
169 | ,p_lov_type=>'STATIC'
170 | );
171 | wwv_flow_api.create_plugin_attr_value(
172 | p_id=>wwv_flow_api.id(15301637796637240)
173 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
174 | ,p_display_sequence=>5
175 | ,p_display_value=>'SVG image'
176 | ,p_return_value=>'SVG'
177 | );
178 | wwv_flow_api.create_plugin_attr_value(
179 | p_id=>wwv_flow_api.id(19204051603103163)
180 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
181 | ,p_display_sequence=>10
182 | ,p_display_value=>'HTML Table'
183 | ,p_return_value=>'HTML'
184 | );
185 | wwv_flow_api.create_plugin_attr_value(
186 | p_id=>wwv_flow_api.id(19204426782104803)
187 | ,p_plugin_attribute_id=>wwv_flow_api.id(19203464560101742)
188 | ,p_display_sequence=>20
189 | ,p_display_value=>'BMP Image'
190 | ,p_return_value=>'BMP'
191 | );
192 | wwv_flow_api.create_plugin_attribute(
193 | p_id=>wwv_flow_api.id(19206265959135863)
194 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
195 | ,p_attribute_scope=>'COMPONENT'
196 | ,p_attribute_sequence=>3
197 | ,p_display_sequence=>30
198 | ,p_prompt=>'Module size'
199 | ,p_attribute_type=>'NUMBER'
200 | ,p_is_required=>true
201 | ,p_default_value=>'8'
202 | ,p_display_length=>5
203 | ,p_max_length=>2
204 | ,p_unit=>'pixels'
205 | ,p_supported_ui_types=>'DESKTOP'
206 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
207 | ,p_is_translatable=>false
208 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
209 | ,p_depending_on_has_to_exist=>true
210 | ,p_depending_on_condition_type=>'IN_LIST'
211 | ,p_depending_on_expression=>'HTML,SVG'
212 | );
213 | wwv_flow_api.create_plugin_attribute(
214 | p_id=>wwv_flow_api.id(19207654617152716)
215 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
216 | ,p_attribute_scope=>'COMPONENT'
217 | ,p_attribute_sequence=>4
218 | ,p_display_sequence=>40
219 | ,p_prompt=>'Image size'
220 | ,p_attribute_type=>'NUMBER'
221 | ,p_is_required=>true
222 | ,p_display_length=>5
223 | ,p_max_length=>4
224 | ,p_unit=>'pixels'
225 | ,p_is_translatable=>false
226 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
227 | ,p_depending_on_has_to_exist=>true
228 | ,p_depending_on_condition_type=>'EQUALS'
229 | ,p_depending_on_expression=>'BMP'
230 | );
231 | wwv_flow_api.create_plugin_attribute(
232 | p_id=>wwv_flow_api.id(19208230004156464)
233 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
234 | ,p_attribute_scope=>'COMPONENT'
235 | ,p_attribute_sequence=>5
236 | ,p_display_sequence=>15
237 | ,p_prompt=>'Margines'
238 | ,p_attribute_type=>'CHECKBOX'
239 | ,p_is_required=>true
240 | ,p_default_value=>'N'
241 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
242 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
243 | ,p_is_translatable=>false
244 | );
245 | wwv_flow_api.create_plugin_attribute(
246 | p_id=>wwv_flow_api.id(15310884392722565)
247 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
248 | ,p_attribute_scope=>'COMPONENT'
249 | ,p_attribute_sequence=>6
250 | ,p_display_sequence=>60
251 | ,p_prompt=>'Module color'
252 | ,p_attribute_type=>'TEXT'
253 | ,p_is_required=>false
254 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
255 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
256 | ,p_is_translatable=>false
257 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
258 | ,p_depending_on_has_to_exist=>true
259 | ,p_depending_on_condition_type=>'EQUALS'
260 | ,p_depending_on_expression=>'SVG'
261 | ,p_examples=>'black | red | rgb(255, 0, 0) | #FF0000'
262 | ,p_help_text=>'Module color (as named color, rgb function or HEX# notification).'
263 | );
264 | wwv_flow_api.create_plugin_attribute(
265 | p_id=>wwv_flow_api.id(15311493488724950)
266 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
267 | ,p_attribute_scope=>'COMPONENT'
268 | ,p_attribute_sequence=>7
269 | ,p_display_sequence=>70
270 | ,p_prompt=>'Background color'
271 | ,p_attribute_type=>'TEXT'
272 | ,p_is_required=>false
273 | ,p_is_translatable=>false
274 | ,p_depending_on_attribute_id=>wwv_flow_api.id(19203464560101742)
275 | ,p_depending_on_has_to_exist=>true
276 | ,p_depending_on_condition_type=>'EQUALS'
277 | ,p_depending_on_expression=>'SVG'
278 | );
279 | wwv_flow_api.create_plugin_attribute(
280 | p_id=>wwv_flow_api.id(15320807577751337)
281 | ,p_plugin_id=>wwv_flow_api.id(19166686046667066)
282 | ,p_attribute_scope=>'COMPONENT'
283 | ,p_attribute_sequence=>8
284 | ,p_display_sequence=>80
285 | ,p_prompt=>'Rounded module edges'
286 | ,p_attribute_type=>'NUMBER'
287 | ,p_is_required=>false
288 | ,p_unit=>'pixel'
289 | ,p_supported_ui_types=>'DESKTOP:JQM_SMARTPHONE'
290 | ,p_supported_component_types=>'APEX_APPLICATION_PAGE_ITEMS'
291 | ,p_is_translatable=>false
292 | );
293 | end;
294 | /
295 | begin
296 | wwv_flow_api.import_end(p_auto_install_sup_obj => nvl(wwv_flow_application_install.get_auto_install_sup_obj, false), p_is_component_import => true);
297 | commit;
298 | end;
299 | /
300 | set verify on feedback on define on
301 | prompt ...done
302 |
--------------------------------------------------------------------------------
/package/ZT_QR.pks:
--------------------------------------------------------------------------------
1 | create or replace PACKAGE ZT_QR AUTHID DEFINER AS
2 | /******************************************************************************
3 | Author: Zoran Tica
4 | ZT-TECH, racunalni�ke storitve s.p.
5 | http://www.zt-tech.eu
6 |
7 | PURPOSE: A package for QR code data and image generation
8 |
9 | REVISIONS:
10 | Ver Date Author Description
11 | --------- ---------- --------------- ------------------------------------
12 | 1.0 18/08/2018 Zoran Tica First version of package.
13 | 1.1 26/05/2019 Zoran Tica Added UTF-8 support, fixed minor BUGs for debug display
14 | 1.2 15/12/2019 Zoran Tica Fixed "_" and "%" BUG
15 | 1.3 13/03/2020 Zoran Tica Added function f_qr_as_long_raw
16 | 1.4 07/01/2021 Zoran Tica Terminator BUG
17 | 1.5 05/02/2021 Zoran Tica older databases compatibility (10g)
18 | f_integer_2_binary - LISTAGG replaced with pure PL SQL
19 | f_get_version - XMLTABLE replaced with local function f_explode
20 | 2.0 09/02/2021 Zoran Tica SVG files support
21 | 2.1 21/08/2023 Zoran Tica Display logo in QR code (for SVG QR Code representation)
22 | 2.2 24/06/2024 k0mita Select a QR code and background color for BMP representation
23 |
24 |
25 | ----------------------------------------------------------------------------
26 | Copyright (C) 2018 - Zoran Tica
27 |
28 | Permission is hereby granted, free of charge, to any person obtaining a copy
29 | of this software and associated documentation files (the "Software"), to deal
30 | in the Software without restriction, including without limitation the rights
31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32 | copies of the Software, and to permit persons to whom the Software is
33 | furnished to do so, subject to the following conditions:
34 |
35 | The above copyright notice and this permission notice shall be included in
36 | all copies or substantial portions of the Software.
37 |
38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44 | THE SOFTWARE.
45 | ----------------------------------------------------------------------------
46 | */
47 |
48 |
49 | /*
50 | Error correction modes:
51 | L - Low Recovers 7% of data
52 | M - Medium Recovers 15% of data
53 | Q - Quartile Recovers 25% of data
54 | H - High Recovers 30% of data
55 | */
56 |
57 |
58 | /*
59 | Procedure generates QR code data as varchar2 variable filled with 0 and 1
60 | 0 is white module, 1 is black
61 | Lines are separated with chr(10)
62 |
63 | IN parameters:
64 | p_data - data that is going to be encoded into QR code
65 | p_error_correction - error correction level (values L, M, Q or H)
66 |
67 | OUT parameters:
68 | p_qr - generated QR code data in format "row (1110100010100...) || newline (chr 10) || row || newline..."
69 | p_matrix_size - matrix size in modules (21, 25, 29...)
70 | */
71 | PROCEDURE p_generate_qr_data(
72 | p_data varchar2,
73 | p_error_correction varchar2,
74 | p_qr OUT NOCOPY varchar2,
75 | p_matrix_size OUT pls_integer
76 | );
77 |
78 |
79 | /*
80 | Procedure generates QR code data as varchar2 variable filled with 0 and 1
81 | 0 is white module, 1 is black
82 | Lines are separated with chr(10)
83 | Debug is printed as DBMS_OUTPUT
84 | There are 3 levels of debug (1, 2 or 3 - low, medium, high)
85 |
86 | IN parameters:
87 | p_data - data that is going to be encoded into QR code
88 | p_error_correction - error correction level (values L, M, Q or H)
89 | p_debug - should DBMS OUTPUT be printed
90 | p_debug_level - debug level (1, 2, 3...) - details to be printed in debug output
91 | p_masking_out - which masking (values 0-7) should be displayed; null -> the best masking will be calculated and selected automatically
92 |
93 | OUT parameters:
94 | p_qr - generated QR code data in format "row (1110100010100) || newline (chr 10) || row || newline..."
95 | p_matrix_size - matrix size in modules (21, 25, 29...)
96 |
97 |
98 | Testing code (enable DBMS OUTPUT for debug!):
99 | DECLARE
100 | lcQR varchar2(32727);
101 | lnMatrixSize pls_integer;
102 | BEGIN
103 | ZT_QR.p_qr_debug(
104 | p_data => 'http://www.zt-tech.eu',
105 | p_error_correction => 'Q',
106 | p_debug => true,
107 | p_debug_level => 2,
108 | p_qr => lcQR,
109 | p_matrix_size => lnMatrixSize
110 | );
111 | END;
112 |
113 | */
114 | PROCEDURE p_qr_debug(
115 | p_data varchar2,
116 | p_error_correction varchar2,
117 | p_debug boolean default true,
118 | p_debug_level pls_integer default 1,
119 | p_masking_out pls_integer default null,
120 | p_qr OUT NOCOPY varchar2,
121 | p_matrix_size OUT pls_integer
122 | );
123 |
124 |
125 |
126 | /*
127 | Function return HTML code for HTML table element representing QR code
128 | Modules are shown as table cells
129 | No additional data (CSS or HTML code) is needed to show table in HTML page
130 |
131 | IN parameters:
132 | p_data - data that is going to be encoded into QR code
133 | p_error_correction - error correction level (values L, M, Q or H)
134 | p_module_size_in_px - width and height of module (table cell)
135 | p_margines - should white margine around QR code (4 modules wide) be generated
136 | */
137 | FUNCTION f_qr_as_html_table(
138 | p_data varchar2, --data going to be encoded into QR code
139 | p_error_correction varchar2, --L, M, Q or H
140 | p_module_size_in_px pls_integer default 8, --module size in pixels
141 | p_margines boolean default false --margines around QR code (4 modules)
142 | ) RETURN clob;
143 |
144 | /*
145 | Procedure prints HTML code for HTML table element using HTP.P procedure
146 | HTML code is prepared in function f_qr_as_html_table
147 |
148 | IN parameters:
149 | p_data - data that is going to be encoded into QR code
150 | p_error_correction - error correction level (values L, M, Q or H)
151 | p_module_size_in_px - width and height of module (table cell)
152 | p_margines - should white margine around QR code (4 modules wide) be generated
153 | */
154 | PROCEDURE p_qr_as_html_table(
155 | p_data varchar2, --data going to be encoded into QR code
156 | p_error_correction varchar2, --L, M, Q or H
157 | p_module_size_in_px pls_integer default 8, --module size in pixels
158 | p_margines boolean default false --margines around QR code (4 modules)
159 | );
160 |
161 |
162 | /*
163 | Function returns black and white BMP image with QR code
164 | Modules are 8x8 pixels large
165 |
166 | IN parameters:
167 | p_data - data that is going to be encoded into QR code
168 | p_error_correction - error correction level (values L, M, Q or H)
169 | p_margines - should white margine around QR code (4 modules wide) be generated
170 | p_foreground_color -- HEX representation of the RGB values of the foreground color (default black)
171 | p_background_color -- HEX representation of the RGB values of the background color (default white)
172 |
173 | Suggested HEX foreground colors:
174 | Blue - 002db3
175 | Red - 990000
176 | Green - 008000
177 | Brown - 663300
178 | Orange - ff9900
179 | Pink - cc0066
180 | Magenta - cc00cc
181 | Gray - 737373
182 | */
183 |
184 | FUNCTION f_qr_as_bmp(
185 | p_data varchar2, --data going to be encoded into QR code
186 | p_error_correction varchar2, --L, M, Q or H
187 | p_margines varchar2 default 'N', --margines around QR code (4 modules) - values Y or N
188 | p_foreground_color varchar2 default '000000', -- HEX representation of the RGB values of the foreground color
189 | p_background_color varchar2 default 'FFFFFF'-- HEX representation of the RGB values of the background color
190 | ) RETURN blob;
191 |
192 | FUNCTION f_qr_as_long_raw(
193 | p_data varchar2, --data going to be encoded into QR code
194 | p_error_correction varchar2, --L, M, Q or H
195 | p_margines varchar2 default 'N' --margines around QR code (4 modules) - values Y or N
196 | ) RETURN long raw;
197 |
198 |
199 | /*
200 | Procedure shows QR code as black and white BMP image
201 | Printed is HTML img tag with base64 image in it
202 |
203 | IN parameters:
204 | p_data - data that is going to be encoded into QR code
205 | p_error_correction - error correction level (values L, M, Q or H)
206 | p_image_size_px - image size in pixels
207 | p_margines - should white margine around QR code (4 modules wide) be generated
208 | */
209 | PROCEDURE p_qr_as_img_tag_base64(
210 | p_data varchar2, --data going to be encoded into QR code
211 | p_error_correction varchar2, --L, M, Q or H
212 | p_image_size_px pls_integer,
213 | p_margines varchar2 default 'N' --margines around QR code (4 modules) - values Y or N
214 | );
215 |
216 |
217 |
218 | /*
219 | Function returns SVG image with QR code
220 |
221 | IN parameters:
222 | p_data - data that is going to be encoded into QR code
223 | p_error_correction - error correction level (values L, M, Q or H)
224 | p_margines_yn - should white margine around QR code (4 modules wide) be generated; values 'Y' or 'N'
225 | p_module_size_px - width and height of one module
226 | p_module_color - module color; colors can be defined as named colors (for example black, red, white...), using rgb function (for example rgb(255, 0, 0) ) or HEX values (for example #FF0000)
227 | p_background_color - background color; colors can be defined as named colors (for example black, red white...), using rgb function (for example rgb(255, 0, 0) ) or HEX values (for example #FF0000)
228 | p_module_rounded_px - if modules should have rounded edges (if size of this parameter is half the module size (or larger) then modules are represented as circles)
229 | p_logo_yn - should logo be displayed on not (values Y / N)
230 | p_logo_size_percent - logo background rectangle size (in percentages) related to QR code size
231 | p_logo_image - logo image (URL reference or base64 content)
232 | p_logo_back_rect_yn - should logo background rectangle be displayed or not
233 | p_logo_back_rect_color - logo background rectangle color
234 | p_logo_back_rect_round_px - logo background rectangle rounded edges
235 | p_logo_margine_px - a margine between logo and background rectangle
236 |
237 | Procedure prints SVG image using HTP.P procedure (can be used to print SVG image directly into HTML code)
238 | */
239 | FUNCTION f_qr_as_svg(
240 | p_data varchar2, --data going to be encoded into QR code
241 | p_error_correction varchar2, --L, M, Q or H
242 | p_module_size_px pls_integer default 8, --modul size in pixels
243 | p_margines_yn varchar2 default 'N', --margines around QR code (4 modules) - values Y or N
244 | p_module_color varchar2 default 'black', --colors are defined as SVG named colors OR rgb (with # or rgb function)
245 | p_background_color varchar2 default 'white',
246 | p_module_rounded_px pls_integer default 0, --0 - sharp corners; > 0 - rounded in pixels
247 | p_logo_yn varchar2 default 'N',
248 | p_logo_size_percent number default 20,
249 | p_logo_image clob default null,
250 | p_logo_back_rect_yn varchar2 default 'Y',
251 | p_logo_back_rect_color varchar2 default 'white',
252 | p_logo_back_rect_round_px pls_integer default 0,
253 | p_logo_margine_px number default 5
254 | ) RETURN clob;
255 |
256 | PROCEDURE p_qr_as_svg(
257 | p_data varchar2, --data going to be encoded into QR code
258 | p_error_correction varchar2, --L, M, Q or H
259 | p_module_size_px pls_integer default 8, --modul size in pixels
260 | p_margines_yn varchar2 default 'N', --margines around QR code (4 modules) - values Y or N
261 | p_module_color varchar2 default 'black', --colors are defined as SVG named colors OR rgb (with # or rgb function)
262 | p_background_color varchar2 default 'white',
263 | p_module_rounded_px pls_integer default 0, --0 - sharp corners; > 0 - rounded in pixels
264 | p_logo_yn varchar2 default 'N',
265 | p_logo_size_percent number default 20,
266 | p_logo_image clob default null,
267 | p_logo_back_rect_yn varchar2 default 'Y',
268 | p_logo_back_rect_color varchar2 default 'white',
269 | p_logo_back_rect_round_px pls_integer default 0,
270 | p_logo_margine_px number default 5
271 | );
272 |
273 |
274 |
275 | /*
276 | Utility procedure which saves generated BMP file containing QR code on server side (directory)
277 | */
278 | PROCEDURE p_save_file(
279 | p_document blob,
280 | p_file_name varchar2,
281 | p_folder varchar2
282 | );
283 |
284 | END ZT_QR;
285 | /
286 |
--------------------------------------------------------------------------------
/package/ZT_QR.pkb:
--------------------------------------------------------------------------------
1 | CREATE OR REPLACE PACKAGE BODY ZT_QR AS
2 |
3 | --C O N S T A N T S
4 |
5 | --data mode
6 | cNumericMode CONSTANT pls_integer := 1;
7 | cAlphanumericMode CONSTANT pls_integer := 2;
8 | cByteMode CONSTANT pls_integer := 3;
9 | cKanjiMode CONSTANT pls_integer := 4;
10 |
11 |
12 | --V A R I A B L E S
13 |
14 | --debug
15 | gpbDebug boolean := false;
16 | gpnDebugLevel pls_integer := 1;
17 |
18 | --mode and version
19 | gpnMode pls_integer;
20 | gpnVersion pls_integer;
21 |
22 | --Error Correction Code Words and Block Information
23 | TYPE r_err_cor IS RECORD(
24 | total_no_of_data_cw pls_integer,
25 | ec_cw_per_block pls_integer,
26 | blocks_in_g1 pls_integer,
27 | cw_in_g1 pls_integer,
28 | blocks_in_g2 pls_integer,
29 | cw_in_g2 pls_integer);
30 |
31 | TYPE t_err_cor IS TABLE OF r_err_cor INDEX BY varchar2(10);
32 |
33 | gprErrCorInfo t_err_cor;
34 |
35 | --logs and antilogs
36 | TYPE t_log_anti IS TABLE OF pls_integer INDEX BY pls_integer;
37 | gprLog t_log_anti;
38 | gprAntiLog t_log_anti;
39 |
40 | --matrix
41 | TYPE t_row IS TABLE OF varchar2(1);
42 | TYPE t_column IS TABLE OF t_row;
43 | TYPE t_masking IS TABLE OF t_column INDEX BY pls_integer;
44 |
45 | gprMatrix t_column := t_column();
46 | gprMasking t_masking;
47 |
48 |
49 |
50 | --DEBUG FUNCS AND PROCS
51 | PROCEDURE p_debug(
52 | p_text varchar2,
53 | p_level pls_integer default 1,
54 | p_new_line boolean default true) IS
55 | BEGIN
56 | if gpbDebug and p_level <= gpnDebugLevel then
57 | if p_new_line then
58 | DBMS_OUTPUT.put_line(p_text);
59 | else
60 | DBMS_OUTPUT.put(p_text);
61 | end if;
62 | end if;
63 | END;
64 |
65 |
66 | PROCEDURE p_dbms_output_matrix(
67 | p_matrix t_column,
68 | p_level pls_integer default 1) IS
69 |
70 | lcQR varchar2(200);
71 |
72 | BEGIN
73 | FOR t IN 1 .. p_matrix.count LOOP
74 | lcQR := null;
75 | FOR p IN 1 .. p_matrix.count LOOP
76 | lcQR := lcQR || nvl(p_matrix(t)(p), 'X');
77 | END LOOP;
78 | p_debug(lcQR, p_level);
79 | END LOOP;
80 | END;
81 |
82 |
83 | --UTILITY FUNCS AND PROCS
84 | FUNCTION bitor(p1 number, p2 number) RETURN number IS
85 | BEGIN
86 | RETURN p1 - bitand(p1, p2) + p2;
87 | END;
88 |
89 | FUNCTION bitxor(p1 number, p2 number) RETURN number IS
90 | BEGIN
91 | RETURN bitor(p1, p2) - bitand(p1, p2);
92 | END;
93 |
94 | FUNCTION bin2dec(p_binval varchar2) RETURN pls_integer IS
95 | lnResult number := 0;
96 | BEGIN
97 | FOR t IN 1 .. length(p_binval) LOOP
98 | lnResult := (lnResult * 2) + to_number(substr(p_binval, t, 1));
99 | END LOOP;
100 |
101 | RETURN lnResult;
102 | END bin2dec;
103 |
104 | /*
105 | FUNCTION f_integer_2_binary(p_integer pls_integer) RETURN varchar2 IS
106 | lcBinary varchar2(100);
107 | BEGIN
108 | SELECT LISTAGG(SIGN(BITAND(p_integer, POWER(2, LEVEL-1))),'') WITHIN GROUP(ORDER BY LEVEL DESC)
109 | INTO lcBinary
110 | FROM dual
111 | CONNECT BY POWER(2, LEVEL-1) <= p_integer;
112 |
113 | RETURN lcBinary;
114 | END;
115 | */
116 |
117 | --function changed to pure PL/SQL version
118 | --also compatible with older databases (10g)
119 | FUNCTION f_integer_2_binary(p_integer pls_integer) RETURN varchar2 IS
120 | lcBinary varchar2(100);
121 | lnTemp number := p_integer;
122 |
123 | BEGIN
124 | if p_integer <> 0 then
125 | WHILE ( lnTemp > 0 ) LOOP
126 | lcBinary := mod(lnTemp, 2) || lcBinary;
127 | lnTemp := trunc( lnTemp / 2 );
128 | END LOOP;
129 | else
130 | lcBinary := '0';
131 | end if;
132 |
133 | RETURN lcBinary;
134 | END f_integer_2_binary;
135 |
136 |
137 | --INIT FUNCS AND PROCS
138 | PROCEDURE p_fill_log_antilog IS
139 | lnVal pls_integer;
140 | lnPrevVal pls_integer;
141 | BEGIN
142 | FOR t IN 0 .. 255 LOOP
143 | if t = 0 then
144 | lnVal := 1;
145 | else
146 | lnVal := lnPrevVal * 2;
147 | if lnVal > 255 then
148 | lnVal := bitxor(lnVal, 285);
149 | end if;
150 | end if;
151 |
152 | gprLog(t) := lnVal;
153 | gprAntiLog(lnVal) := t;
154 |
155 | lnPrevVal := lnVal;
156 |
157 | p_debug('Log for ' || t || ': ' || gprLog(t), 4);
158 |
159 | END LOOP;
160 | END;
161 |
162 | FUNCTION f_matrix_size RETURN pls_integer IS
163 | BEGIN
164 | --minimal matrix size is 21x21 module; every next version is 4 modules larger
165 | RETURN ((gpnVersion - 1) * 4) + 21;
166 | END;
167 |
168 |
169 |
170 | PROCEDURE p_init_matrix IS
171 |
172 | TYPE t_col IS TABLE OF pls_integer;
173 | TYPE t_alignment_pos IS TABLE OF t_col;
174 | lrAlignPos t_alignment_pos := t_alignment_pos();
175 |
176 | lcModule varchar2(1);
177 |
178 | PROCEDURE p_add_finder(p_column pls_integer, p_row pls_integer) IS
179 | BEGIN
180 | --outer black square
181 | FOR t IN 0 .. 6 LOOP
182 | gprMatrix(p_column + t)(p_row) := '3';
183 | gprMatrix(p_column + t)(p_row + 6) := '3';
184 | gprMatrix(p_column)(p_row + t) := '3';
185 | gprMatrix(p_column + 6)(p_row + t) := '3';
186 | END LOOP;
187 |
188 | --inner white square
189 | FOR t IN 0 .. 4 LOOP
190 | gprMatrix(p_column + 1 + t)(p_row + 1) := '2';
191 | gprMatrix(p_column + 1 + t)(p_row + 1 + 4) := '2';
192 | gprMatrix(p_column + 1)(p_row + 1 + t) := '2';
193 | gprMatrix(p_column + 1 + 4)(p_row + 1 + t) := '2';
194 | END LOOP;
195 |
196 | --inner black square
197 | FOR t IN 0 .. 2 LOOP
198 | FOR p IN 0 .. 2 LOOP
199 | gprMatrix(p_column + 2 + t)(p_row + 2 + p) := '3';
200 | END LOOP;
201 | END LOOP;
202 |
203 | END;
204 |
205 | PROCEDURE p_init_alignment IS
206 | BEGIN
207 | lrAlignPos.delete;
208 | lrAlignPos.extend(40);
209 |
210 | lrAlignPos(1) := t_col(0);
211 | lrAlignPos(2) := t_col(6, 18);
212 | lrAlignPos(3) := t_col(6, 22);
213 | lrAlignPos(4) := t_col(6, 26);
214 | lrAlignPos(5) := t_col(6, 30);
215 | lrAlignPos(6) := t_col(6, 34);
216 | lrAlignPos(7) := t_col(6, 22, 38);
217 | lrAlignPos(8) := t_col(6, 24, 42);
218 | lrAlignPos(9) := t_col(6, 26, 46);
219 | lrAlignPos(10) := t_col(6, 28, 50);
220 | lrAlignPos(11) := t_col(6, 30, 54);
221 | lrAlignPos(12) := t_col(6, 32, 58);
222 | lrAlignPos(13) := t_col(6, 34, 62);
223 | lrAlignPos(14) := t_col(6, 26, 46, 66);
224 | lrAlignPos(15) := t_col(6, 26, 48, 70);
225 | lrAlignPos(16) := t_col(6, 26, 50, 74);
226 | lrAlignPos(17) := t_col(6, 30, 54, 78);
227 | lrAlignPos(18) := t_col(6, 30, 56, 82);
228 | lrAlignPos(19) := t_col(6, 30, 58, 86);
229 | lrAlignPos(20) := t_col(6, 34, 62, 90);
230 | lrAlignPos(21) := t_col(6, 28, 50, 72, 94);
231 | lrAlignPos(22) := t_col(6, 26, 50, 74, 98);
232 | lrAlignPos(23) := t_col(6, 30, 54, 78, 102);
233 | lrAlignPos(24) := t_col(6, 28, 54, 80, 106);
234 | lrAlignPos(25) := t_col(6, 32, 58, 84, 110);
235 | lrAlignPos(26) := t_col(6, 30, 58, 86, 114);
236 | lrAlignPos(27) := t_col(6, 34, 62, 90, 118);
237 | lrAlignPos(28) := t_col(6, 26, 50, 74, 98, 122 );
238 | lrAlignPos(29) := t_col(6, 30, 54, 78, 102, 126);
239 | lrAlignPos(30) := t_col(6, 26, 52, 78, 104, 130 );
240 | lrAlignPos(31) := t_col(6, 30, 56, 82, 108, 134 );
241 | lrAlignPos(32) := t_col(6, 34, 60, 86, 112, 138 );
242 | lrAlignPos(33) := t_col(6, 30, 58, 86, 114, 142 );
243 | lrAlignPos(34) := t_col(6, 34, 62, 90, 118, 146 );
244 | lrAlignPos(35) := t_col(6, 30, 54, 78, 102, 126, 150);
245 | lrAlignPos(36) := t_col(6, 24, 50, 76, 102, 128, 154);
246 | lrAlignPos(37) := t_col(6, 28, 54, 80, 106, 132, 158);
247 | lrAlignPos(38) := t_col(6, 32, 58, 84, 110, 136, 162);
248 | lrAlignPos(39) := t_col(6, 26, 54, 82, 110, 138, 166);
249 | lrAlignPos(40) := t_col(6, 30, 58, 86, 114, 142, 170);
250 |
251 | END;
252 |
253 | PROCEDURE p_add_alignment(p_column pls_integer, p_row pls_integer) IS
254 | BEGIN
255 | --check if coordinates are OK and alignment is on matrix
256 | if p_column - 2 < 1 or p_column + 2 > f_matrix_size or p_row - 2 < 1 or p_row + 2 > f_matrix_size then
257 | p_debug('Alignment on ' || p_column || ', ' || p_row || ' is outside of matrix! Skipping...', 2);
258 | RETURN;
259 | end if;
260 |
261 | --first check if overlap with existing finders; if overlaps then do not draw finder
262 | FOR t IN p_column - 2 .. p_column + 2 LOOP
263 | FOR p IN p_row - 2 .. p_row + 2 LOOP
264 | if gprMatrix(p)(t) is not null then
265 | p_debug('Alignment on ' || p_column || ', ' || p_row || ' overlaps with finder! Skipping...', 2);
266 | RETURN;
267 | end if;
268 | END LOOP;
269 | END LOOP;
270 |
271 | --draw alignment
272 | --outer black square
273 | FOR t IN 0 .. 4 LOOP
274 | gprMatrix(p_row - 2)(p_column - 2 + t) := '3';
275 | gprMatrix(p_row - 2 + t)(p_column - 2) := '3';
276 | gprMatrix(p_row + 2)(p_column - 2 + t) := '3';
277 | gprMatrix(p_row - 2 + t)(p_column + 2) := '3';
278 | END LOOP;
279 |
280 | --inner white square and center module
281 | FOR t IN 0 .. 2 LOOP
282 | FOR p IN 0 .. 2 LOOP
283 | gprMatrix(p_row - 1 + t)(p_column - 1 + p) := '2';
284 | END LOOP;
285 | END LOOP;
286 | gprMatrix(p_row)(p_column) := '3';
287 |
288 |
289 | END;
290 |
291 | BEGIN
292 | p_debug('Matrix size: ' || f_matrix_size || 'x' || f_matrix_size || ' modules', 2);
293 |
294 | --collection initialization
295 | gprMatrix.delete;
296 |
297 | gprMatrix.extend(f_matrix_size);
298 | FOR t IN 1 .. f_matrix_size LOOP
299 | gprMatrix(t) := t_row();
300 | gprMatrix(t).extend(f_matrix_size);
301 | END LOOP;
302 |
303 |
304 | --add Finder Patterns (3x)
305 | p_add_finder(1, 1);
306 | p_add_finder(f_matrix_size - 6, 1);
307 | p_add_finder(1, f_matrix_size - 6);
308 |
309 |
310 | --add Separators
311 | FOR t IN 0 .. 7 LOOP
312 | --upper left
313 | gprMatrix(1 + t)(1 + 7) := '2';
314 | gprMatrix(1 + 7)(1 + t) := '2';
315 |
316 | --lower left
317 | gprMatrix(f_matrix_size - 7 + t)(1 + 7) := '2';
318 | gprMatrix(f_matrix_size - 7)(1 + t) := '2';
319 |
320 | --upper right
321 | gprMatrix(1 + t)(f_matrix_size - 7) := '2';
322 | gprMatrix(1 + 7)(f_matrix_size - 7 + t) := '2';
323 | END LOOP;
324 |
325 |
326 | --add Alignment Patterns (for versions larger then 1)
327 | p_init_alignment;
328 |
329 | if gpnVersion > 1 then
330 | FOR t IN 1 .. lrAlignPos(gpnVersion).count LOOP
331 | FOR p IN 1 .. lrAlignPos(gpnVersion).count LOOP
332 | p_add_alignment(lrAlignPos(gpnVersion)(t) + 1, lrAlignPos(gpnVersion)(p) + 1);
333 | END LOOP;
334 | END LOOP;
335 | end if;
336 |
337 |
338 | --Timing Patterns
339 | FOR t IN 9 .. f_matrix_size - 8 LOOP
340 | if t mod 2 <> 0 then
341 | lcModule := '3'; --first module is black, then white, then black...
342 | else
343 | lcModule := '2';
344 | end if;
345 |
346 | gprMatrix(7)(t) := lcModule;
347 | gprMatrix(t)(7) := lcModule;
348 | END LOOP;
349 |
350 |
351 | --Dark Module
352 | gprMatrix(f_matrix_size - 7)(9) := '3';
353 |
354 | --Reserved Areas (Format Information Area, Version Information Area)
355 | --will be filled with actual values later
356 |
357 | --Format Information Area, placeholder values are dots
358 | FOR t IN 1 .. 9 LOOP
359 | if gprMatrix(9)(t) is null then
360 | gprMatrix(9)(t) := '.';
361 | end if;
362 |
363 | if gprMatrix(t)(9) is null then
364 | gprMatrix(t)(9) := '.';
365 | end if;
366 | END LOOP;
367 |
368 | FOR t IN 1 .. 8 LOOP
369 | if gprMatrix(f_matrix_size - t + 1)(9) is null then
370 | gprMatrix(f_matrix_size - t + 1)(9) := '.';
371 | end if;
372 |
373 | if gprMatrix(9)(f_matrix_size - t + 1) is null then
374 | gprMatrix(9)(f_matrix_size - t + 1) := '.';
375 | end if;
376 | END LOOP;
377 |
378 | --Version Information Area, placeholder values are *
379 | --it aplies only to versions 7 and larger
380 | if gpnVersion >= 7 then
381 | FOR t IN 1 .. 6 LOOP
382 | gprMatrix(f_matrix_size - 8)(t) := '*';
383 | gprMatrix(f_matrix_size - 9)(t) := '*';
384 | gprMatrix(f_matrix_size - 10)(t) := '*';
385 |
386 | gprMatrix(t)(f_matrix_size - 8) := '*';
387 | gprMatrix(t)(f_matrix_size - 9) := '*';
388 | gprMatrix(t)(f_matrix_size - 10) := '*';
389 |
390 | END LOOP;
391 | end if;
392 | END;
393 |
394 |
395 | PROCEDURE p_fill_err_cor IS
396 | BEGIN
397 | gprErrCorInfo('1-L').total_no_of_data_cw := 19; gprErrCorInfo('1-L').ec_cw_per_block := 7; gprErrCorInfo('1-L').blocks_in_g1 := 1; gprErrCorInfo('1-L').cw_in_g1 := 19; gprErrCorInfo('1-L').blocks_in_g2 := null; gprErrCorInfo('1-L').cw_in_g2 := null;
398 | gprErrCorInfo('1-M').total_no_of_data_cw := 16; gprErrCorInfo('1-M').ec_cw_per_block := 10; gprErrCorInfo('1-M').blocks_in_g1 := 1; gprErrCorInfo('1-M').cw_in_g1 := 16; gprErrCorInfo('1-M').blocks_in_g2 := null; gprErrCorInfo('1-M').cw_in_g2 := null;
399 | gprErrCorInfo('1-Q').total_no_of_data_cw := 13; gprErrCorInfo('1-Q').ec_cw_per_block := 13; gprErrCorInfo('1-Q').blocks_in_g1 := 1; gprErrCorInfo('1-Q').cw_in_g1 := 13; gprErrCorInfo('1-Q').blocks_in_g2 := null; gprErrCorInfo('1-Q').cw_in_g2 := null;
400 | gprErrCorInfo('1-H').total_no_of_data_cw := 9; gprErrCorInfo('1-H').ec_cw_per_block := 17; gprErrCorInfo('1-H').blocks_in_g1 := 1; gprErrCorInfo('1-H').cw_in_g1 := 9; gprErrCorInfo('1-H').blocks_in_g2 := null; gprErrCorInfo('1-H').cw_in_g2 := null;
401 | gprErrCorInfo('2-L').total_no_of_data_cw := 34; gprErrCorInfo('2-L').ec_cw_per_block := 10; gprErrCorInfo('2-L').blocks_in_g1 := 1; gprErrCorInfo('2-L').cw_in_g1 := 34; gprErrCorInfo('2-L').blocks_in_g2 := null; gprErrCorInfo('2-L').cw_in_g2 := null;
402 | gprErrCorInfo('2-M').total_no_of_data_cw := 28; gprErrCorInfo('2-M').ec_cw_per_block := 16; gprErrCorInfo('2-M').blocks_in_g1 := 1; gprErrCorInfo('2-M').cw_in_g1 := 28; gprErrCorInfo('2-M').blocks_in_g2 := null; gprErrCorInfo('2-M').cw_in_g2 := null;
403 | gprErrCorInfo('2-Q').total_no_of_data_cw := 22; gprErrCorInfo('2-Q').ec_cw_per_block := 22; gprErrCorInfo('2-Q').blocks_in_g1 := 1; gprErrCorInfo('2-Q').cw_in_g1 := 22; gprErrCorInfo('2-Q').blocks_in_g2 := null; gprErrCorInfo('2-Q').cw_in_g2 := null;
404 | gprErrCorInfo('2-H').total_no_of_data_cw := 16; gprErrCorInfo('2-H').ec_cw_per_block := 28; gprErrCorInfo('2-H').blocks_in_g1 := 1; gprErrCorInfo('2-H').cw_in_g1 := 16; gprErrCorInfo('2-H').blocks_in_g2 := null; gprErrCorInfo('2-H').cw_in_g2 := null;
405 | gprErrCorInfo('3-L').total_no_of_data_cw := 55; gprErrCorInfo('3-L').ec_cw_per_block := 15; gprErrCorInfo('3-L').blocks_in_g1 := 1; gprErrCorInfo('3-L').cw_in_g1 := 55; gprErrCorInfo('3-L').blocks_in_g2 := null; gprErrCorInfo('3-L').cw_in_g2 := null;
406 | gprErrCorInfo('3-M').total_no_of_data_cw := 44; gprErrCorInfo('3-M').ec_cw_per_block := 26; gprErrCorInfo('3-M').blocks_in_g1 := 1; gprErrCorInfo('3-M').cw_in_g1 := 44; gprErrCorInfo('3-M').blocks_in_g2 := null; gprErrCorInfo('3-M').cw_in_g2 := null;
407 | gprErrCorInfo('3-Q').total_no_of_data_cw := 34; gprErrCorInfo('3-Q').ec_cw_per_block := 18; gprErrCorInfo('3-Q').blocks_in_g1 := 2; gprErrCorInfo('3-Q').cw_in_g1 := 17; gprErrCorInfo('3-Q').blocks_in_g2 := null; gprErrCorInfo('3-Q').cw_in_g2 := null;
408 | gprErrCorInfo('3-H').total_no_of_data_cw := 26; gprErrCorInfo('3-H').ec_cw_per_block := 22; gprErrCorInfo('3-H').blocks_in_g1 := 2; gprErrCorInfo('3-H').cw_in_g1 := 13; gprErrCorInfo('3-H').blocks_in_g2 := null; gprErrCorInfo('3-H').cw_in_g2 := null;
409 | gprErrCorInfo('4-L').total_no_of_data_cw := 80; gprErrCorInfo('4-L').ec_cw_per_block := 20; gprErrCorInfo('4-L').blocks_in_g1 := 1; gprErrCorInfo('4-L').cw_in_g1 := 80; gprErrCorInfo('4-L').blocks_in_g2 := null; gprErrCorInfo('4-L').cw_in_g2 := null;
410 | gprErrCorInfo('4-M').total_no_of_data_cw := 64; gprErrCorInfo('4-M').ec_cw_per_block := 18; gprErrCorInfo('4-M').blocks_in_g1 := 2; gprErrCorInfo('4-M').cw_in_g1 := 32; gprErrCorInfo('4-M').blocks_in_g2 := null; gprErrCorInfo('4-M').cw_in_g2 := null;
411 | gprErrCorInfo('4-Q').total_no_of_data_cw := 48; gprErrCorInfo('4-Q').ec_cw_per_block := 26; gprErrCorInfo('4-Q').blocks_in_g1 := 2; gprErrCorInfo('4-Q').cw_in_g1 := 24; gprErrCorInfo('4-Q').blocks_in_g2 := null; gprErrCorInfo('4-Q').cw_in_g2 := null;
412 | gprErrCorInfo('4-H').total_no_of_data_cw := 36; gprErrCorInfo('4-H').ec_cw_per_block := 16; gprErrCorInfo('4-H').blocks_in_g1 := 4; gprErrCorInfo('4-H').cw_in_g1 := 9; gprErrCorInfo('4-H').blocks_in_g2 := null; gprErrCorInfo('4-H').cw_in_g2 := null;
413 | gprErrCorInfo('5-L').total_no_of_data_cw := 108; gprErrCorInfo('5-L').ec_cw_per_block := 26; gprErrCorInfo('5-L').blocks_in_g1 := 1; gprErrCorInfo('5-L').cw_in_g1 := 108; gprErrCorInfo('5-L').blocks_in_g2 := null; gprErrCorInfo('5-L').cw_in_g2 := null;
414 | gprErrCorInfo('5-M').total_no_of_data_cw := 86; gprErrCorInfo('5-M').ec_cw_per_block := 24; gprErrCorInfo('5-M').blocks_in_g1 := 2; gprErrCorInfo('5-M').cw_in_g1 := 43; gprErrCorInfo('5-M').blocks_in_g2 := null; gprErrCorInfo('5-M').cw_in_g2 := null;
415 | gprErrCorInfo('5-Q').total_no_of_data_cw := 62; gprErrCorInfo('5-Q').ec_cw_per_block := 18; gprErrCorInfo('5-Q').blocks_in_g1 := 2; gprErrCorInfo('5-Q').cw_in_g1 := 15; gprErrCorInfo('5-Q').blocks_in_g2 := 2; gprErrCorInfo('5-Q').cw_in_g2 := 16;
416 | gprErrCorInfo('5-H').total_no_of_data_cw := 46; gprErrCorInfo('5-H').ec_cw_per_block := 22; gprErrCorInfo('5-H').blocks_in_g1 := 2; gprErrCorInfo('5-H').cw_in_g1 := 11; gprErrCorInfo('5-H').blocks_in_g2 := 2; gprErrCorInfo('5-H').cw_in_g2 := 12;
417 | gprErrCorInfo('6-L').total_no_of_data_cw := 136; gprErrCorInfo('6-L').ec_cw_per_block := 18; gprErrCorInfo('6-L').blocks_in_g1 := 2; gprErrCorInfo('6-L').cw_in_g1 := 68; gprErrCorInfo('6-L').blocks_in_g2 := null; gprErrCorInfo('6-L').cw_in_g2 := null;
418 | gprErrCorInfo('6-M').total_no_of_data_cw := 108; gprErrCorInfo('6-M').ec_cw_per_block := 16; gprErrCorInfo('6-M').blocks_in_g1 := 4; gprErrCorInfo('6-M').cw_in_g1 := 27; gprErrCorInfo('6-M').blocks_in_g2 := null; gprErrCorInfo('6-M').cw_in_g2 := null;
419 | gprErrCorInfo('6-Q').total_no_of_data_cw := 76; gprErrCorInfo('6-Q').ec_cw_per_block := 24; gprErrCorInfo('6-Q').blocks_in_g1 := 4; gprErrCorInfo('6-Q').cw_in_g1 := 19; gprErrCorInfo('6-Q').blocks_in_g2 := null; gprErrCorInfo('6-Q').cw_in_g2 := null;
420 | gprErrCorInfo('6-H').total_no_of_data_cw := 60; gprErrCorInfo('6-H').ec_cw_per_block := 28; gprErrCorInfo('6-H').blocks_in_g1 := 4; gprErrCorInfo('6-H').cw_in_g1 := 15; gprErrCorInfo('6-H').blocks_in_g2 := null; gprErrCorInfo('6-H').cw_in_g2 := null;
421 | gprErrCorInfo('7-L').total_no_of_data_cw := 156; gprErrCorInfo('7-L').ec_cw_per_block := 20; gprErrCorInfo('7-L').blocks_in_g1 := 2; gprErrCorInfo('7-L').cw_in_g1 := 78; gprErrCorInfo('7-L').blocks_in_g2 := null; gprErrCorInfo('7-L').cw_in_g2 := null;
422 | gprErrCorInfo('7-M').total_no_of_data_cw := 124; gprErrCorInfo('7-M').ec_cw_per_block := 18; gprErrCorInfo('7-M').blocks_in_g1 := 4; gprErrCorInfo('7-M').cw_in_g1 := 31; gprErrCorInfo('7-M').blocks_in_g2 := null; gprErrCorInfo('7-M').cw_in_g2 := null;
423 | gprErrCorInfo('7-Q').total_no_of_data_cw := 88; gprErrCorInfo('7-Q').ec_cw_per_block := 18; gprErrCorInfo('7-Q').blocks_in_g1 := 2; gprErrCorInfo('7-Q').cw_in_g1 := 14; gprErrCorInfo('7-Q').blocks_in_g2 := 4; gprErrCorInfo('7-Q').cw_in_g2 := 15;
424 | gprErrCorInfo('7-H').total_no_of_data_cw := 66; gprErrCorInfo('7-H').ec_cw_per_block := 26; gprErrCorInfo('7-H').blocks_in_g1 := 4; gprErrCorInfo('7-H').cw_in_g1 := 13; gprErrCorInfo('7-H').blocks_in_g2 := 1; gprErrCorInfo('7-H').cw_in_g2 := 14;
425 | gprErrCorInfo('8-L').total_no_of_data_cw := 194; gprErrCorInfo('8-L').ec_cw_per_block := 24; gprErrCorInfo('8-L').blocks_in_g1 := 2; gprErrCorInfo('8-L').cw_in_g1 := 97; gprErrCorInfo('8-L').blocks_in_g2 := null; gprErrCorInfo('8-L').cw_in_g2 := null;
426 | gprErrCorInfo('8-M').total_no_of_data_cw := 154; gprErrCorInfo('8-M').ec_cw_per_block := 22; gprErrCorInfo('8-M').blocks_in_g1 := 2; gprErrCorInfo('8-M').cw_in_g1 := 38; gprErrCorInfo('8-M').blocks_in_g2 := 2; gprErrCorInfo('8-M').cw_in_g2 := 39;
427 | gprErrCorInfo('8-Q').total_no_of_data_cw := 110; gprErrCorInfo('8-Q').ec_cw_per_block := 22; gprErrCorInfo('8-Q').blocks_in_g1 := 4; gprErrCorInfo('8-Q').cw_in_g1 := 18; gprErrCorInfo('8-Q').blocks_in_g2 := 2; gprErrCorInfo('8-Q').cw_in_g2 := 19;
428 | gprErrCorInfo('8-H').total_no_of_data_cw := 86; gprErrCorInfo('8-H').ec_cw_per_block := 26; gprErrCorInfo('8-H').blocks_in_g1 := 4; gprErrCorInfo('8-H').cw_in_g1 := 14; gprErrCorInfo('8-H').blocks_in_g2 := 2; gprErrCorInfo('8-H').cw_in_g2 := 15;
429 | gprErrCorInfo('9-L').total_no_of_data_cw := 232; gprErrCorInfo('9-L').ec_cw_per_block := 30; gprErrCorInfo('9-L').blocks_in_g1 := 2; gprErrCorInfo('9-L').cw_in_g1 := 116; gprErrCorInfo('9-L').blocks_in_g2 := null; gprErrCorInfo('9-L').cw_in_g2 := null;
430 | gprErrCorInfo('9-M').total_no_of_data_cw := 182; gprErrCorInfo('9-M').ec_cw_per_block := 22; gprErrCorInfo('9-M').blocks_in_g1 := 3; gprErrCorInfo('9-M').cw_in_g1 := 36; gprErrCorInfo('9-M').blocks_in_g2 := 2; gprErrCorInfo('9-M').cw_in_g2 := 37;
431 | gprErrCorInfo('9-Q').total_no_of_data_cw := 132; gprErrCorInfo('9-Q').ec_cw_per_block := 20; gprErrCorInfo('9-Q').blocks_in_g1 := 4; gprErrCorInfo('9-Q').cw_in_g1 := 16; gprErrCorInfo('9-Q').blocks_in_g2 := 4; gprErrCorInfo('9-Q').cw_in_g2 := 17;
432 | gprErrCorInfo('9-H').total_no_of_data_cw := 100; gprErrCorInfo('9-H').ec_cw_per_block := 24; gprErrCorInfo('9-H').blocks_in_g1 := 4; gprErrCorInfo('9-H').cw_in_g1 := 12; gprErrCorInfo('9-H').blocks_in_g2 := 4; gprErrCorInfo('9-H').cw_in_g2 := 13;
433 | gprErrCorInfo('10-L').total_no_of_data_cw := 274; gprErrCorInfo('10-L').ec_cw_per_block := 18; gprErrCorInfo('10-L').blocks_in_g1 := 2; gprErrCorInfo('10-L').cw_in_g1 := 68; gprErrCorInfo('10-L').blocks_in_g2 := 2; gprErrCorInfo('10-L').cw_in_g2 := 69;
434 | gprErrCorInfo('10-M').total_no_of_data_cw := 216; gprErrCorInfo('10-M').ec_cw_per_block := 26; gprErrCorInfo('10-M').blocks_in_g1 := 4; gprErrCorInfo('10-M').cw_in_g1 := 43; gprErrCorInfo('10-M').blocks_in_g2 := 1; gprErrCorInfo('10-M').cw_in_g2 := 44;
435 | gprErrCorInfo('10-Q').total_no_of_data_cw := 154; gprErrCorInfo('10-Q').ec_cw_per_block := 24; gprErrCorInfo('10-Q').blocks_in_g1 := 6; gprErrCorInfo('10-Q').cw_in_g1 := 19; gprErrCorInfo('10-Q').blocks_in_g2 := 2; gprErrCorInfo('10-Q').cw_in_g2 := 20;
436 | gprErrCorInfo('10-H').total_no_of_data_cw := 122; gprErrCorInfo('10-H').ec_cw_per_block := 28; gprErrCorInfo('10-H').blocks_in_g1 := 6; gprErrCorInfo('10-H').cw_in_g1 := 15; gprErrCorInfo('10-H').blocks_in_g2 := 2; gprErrCorInfo('10-H').cw_in_g2 := 16;
437 | gprErrCorInfo('11-L').total_no_of_data_cw := 324; gprErrCorInfo('11-L').ec_cw_per_block := 20; gprErrCorInfo('11-L').blocks_in_g1 := 4; gprErrCorInfo('11-L').cw_in_g1 := 81; gprErrCorInfo('11-L').blocks_in_g2 := null; gprErrCorInfo('11-L').cw_in_g2 := null;
438 | gprErrCorInfo('11-M').total_no_of_data_cw := 254; gprErrCorInfo('11-M').ec_cw_per_block := 30; gprErrCorInfo('11-M').blocks_in_g1 := 1; gprErrCorInfo('11-M').cw_in_g1 := 50; gprErrCorInfo('11-M').blocks_in_g2 := 4; gprErrCorInfo('11-M').cw_in_g2 := 51;
439 | gprErrCorInfo('11-Q').total_no_of_data_cw := 180; gprErrCorInfo('11-Q').ec_cw_per_block := 28; gprErrCorInfo('11-Q').blocks_in_g1 := 4; gprErrCorInfo('11-Q').cw_in_g1 := 22; gprErrCorInfo('11-Q').blocks_in_g2 := 4; gprErrCorInfo('11-Q').cw_in_g2 := 23;
440 | gprErrCorInfo('11-H').total_no_of_data_cw := 140; gprErrCorInfo('11-H').ec_cw_per_block := 24; gprErrCorInfo('11-H').blocks_in_g1 := 3; gprErrCorInfo('11-H').cw_in_g1 := 12; gprErrCorInfo('11-H').blocks_in_g2 := 8; gprErrCorInfo('11-H').cw_in_g2 := 13;
441 | gprErrCorInfo('12-L').total_no_of_data_cw := 370; gprErrCorInfo('12-L').ec_cw_per_block := 24; gprErrCorInfo('12-L').blocks_in_g1 := 2; gprErrCorInfo('12-L').cw_in_g1 := 92; gprErrCorInfo('12-L').blocks_in_g2 := 2; gprErrCorInfo('12-L').cw_in_g2 := 93;
442 | gprErrCorInfo('12-M').total_no_of_data_cw := 290; gprErrCorInfo('12-M').ec_cw_per_block := 22; gprErrCorInfo('12-M').blocks_in_g1 := 6; gprErrCorInfo('12-M').cw_in_g1 := 36; gprErrCorInfo('12-M').blocks_in_g2 := 2; gprErrCorInfo('12-M').cw_in_g2 := 37;
443 | gprErrCorInfo('12-Q').total_no_of_data_cw := 206; gprErrCorInfo('12-Q').ec_cw_per_block := 26; gprErrCorInfo('12-Q').blocks_in_g1 := 4; gprErrCorInfo('12-Q').cw_in_g1 := 20; gprErrCorInfo('12-Q').blocks_in_g2 := 6; gprErrCorInfo('12-Q').cw_in_g2 := 21;
444 | gprErrCorInfo('12-H').total_no_of_data_cw := 158; gprErrCorInfo('12-H').ec_cw_per_block := 28; gprErrCorInfo('12-H').blocks_in_g1 := 7; gprErrCorInfo('12-H').cw_in_g1 := 14; gprErrCorInfo('12-H').blocks_in_g2 := 4; gprErrCorInfo('12-H').cw_in_g2 := 15;
445 | gprErrCorInfo('13-L').total_no_of_data_cw := 428; gprErrCorInfo('13-L').ec_cw_per_block := 26; gprErrCorInfo('13-L').blocks_in_g1 := 4; gprErrCorInfo('13-L').cw_in_g1 := 107; gprErrCorInfo('13-L').blocks_in_g2 := null; gprErrCorInfo('13-L').cw_in_g2 := null;
446 | gprErrCorInfo('13-M').total_no_of_data_cw := 334; gprErrCorInfo('13-M').ec_cw_per_block := 22; gprErrCorInfo('13-M').blocks_in_g1 := 8; gprErrCorInfo('13-M').cw_in_g1 := 37; gprErrCorInfo('13-M').blocks_in_g2 := 1; gprErrCorInfo('13-M').cw_in_g2 := 38;
447 | gprErrCorInfo('13-Q').total_no_of_data_cw := 244; gprErrCorInfo('13-Q').ec_cw_per_block := 24; gprErrCorInfo('13-Q').blocks_in_g1 := 8; gprErrCorInfo('13-Q').cw_in_g1 := 20; gprErrCorInfo('13-Q').blocks_in_g2 := 4; gprErrCorInfo('13-Q').cw_in_g2 := 21;
448 | gprErrCorInfo('13-H').total_no_of_data_cw := 180; gprErrCorInfo('13-H').ec_cw_per_block := 22; gprErrCorInfo('13-H').blocks_in_g1 := 12; gprErrCorInfo('13-H').cw_in_g1 := 11; gprErrCorInfo('13-H').blocks_in_g2 := 4; gprErrCorInfo('13-H').cw_in_g2 := 12;
449 | gprErrCorInfo('14-L').total_no_of_data_cw := 461; gprErrCorInfo('14-L').ec_cw_per_block := 30; gprErrCorInfo('14-L').blocks_in_g1 := 3; gprErrCorInfo('14-L').cw_in_g1 := 115; gprErrCorInfo('14-L').blocks_in_g2 := 1; gprErrCorInfo('14-L').cw_in_g2 := 116;
450 | gprErrCorInfo('14-M').total_no_of_data_cw := 365; gprErrCorInfo('14-M').ec_cw_per_block := 24; gprErrCorInfo('14-M').blocks_in_g1 := 4; gprErrCorInfo('14-M').cw_in_g1 := 40; gprErrCorInfo('14-M').blocks_in_g2 := 5; gprErrCorInfo('14-M').cw_in_g2 := 41;
451 | gprErrCorInfo('14-Q').total_no_of_data_cw := 261; gprErrCorInfo('14-Q').ec_cw_per_block := 20; gprErrCorInfo('14-Q').blocks_in_g1 := 11; gprErrCorInfo('14-Q').cw_in_g1 := 16; gprErrCorInfo('14-Q').blocks_in_g2 := 5; gprErrCorInfo('14-Q').cw_in_g2 := 17;
452 | gprErrCorInfo('14-H').total_no_of_data_cw := 197; gprErrCorInfo('14-H').ec_cw_per_block := 24; gprErrCorInfo('14-H').blocks_in_g1 := 11; gprErrCorInfo('14-H').cw_in_g1 := 12; gprErrCorInfo('14-H').blocks_in_g2 := 5; gprErrCorInfo('14-H').cw_in_g2 := 13;
453 | gprErrCorInfo('15-L').total_no_of_data_cw := 523; gprErrCorInfo('15-L').ec_cw_per_block := 22; gprErrCorInfo('15-L').blocks_in_g1 := 5; gprErrCorInfo('15-L').cw_in_g1 := 87; gprErrCorInfo('15-L').blocks_in_g2 := 1; gprErrCorInfo('15-L').cw_in_g2 := 88;
454 | gprErrCorInfo('15-M').total_no_of_data_cw := 415; gprErrCorInfo('15-M').ec_cw_per_block := 24; gprErrCorInfo('15-M').blocks_in_g1 := 5; gprErrCorInfo('15-M').cw_in_g1 := 41; gprErrCorInfo('15-M').blocks_in_g2 := 5; gprErrCorInfo('15-M').cw_in_g2 := 42;
455 | gprErrCorInfo('15-Q').total_no_of_data_cw := 295; gprErrCorInfo('15-Q').ec_cw_per_block := 30; gprErrCorInfo('15-Q').blocks_in_g1 := 5; gprErrCorInfo('15-Q').cw_in_g1 := 24; gprErrCorInfo('15-Q').blocks_in_g2 := 7; gprErrCorInfo('15-Q').cw_in_g2 := 25;
456 | gprErrCorInfo('15-H').total_no_of_data_cw := 223; gprErrCorInfo('15-H').ec_cw_per_block := 24; gprErrCorInfo('15-H').blocks_in_g1 := 11; gprErrCorInfo('15-H').cw_in_g1 := 12; gprErrCorInfo('15-H').blocks_in_g2 := 7; gprErrCorInfo('15-H').cw_in_g2 := 13;
457 | gprErrCorInfo('16-L').total_no_of_data_cw := 589; gprErrCorInfo('16-L').ec_cw_per_block := 24; gprErrCorInfo('16-L').blocks_in_g1 := 5; gprErrCorInfo('16-L').cw_in_g1 := 98; gprErrCorInfo('16-L').blocks_in_g2 := 1; gprErrCorInfo('16-L').cw_in_g2 := 99;
458 | gprErrCorInfo('16-M').total_no_of_data_cw := 453; gprErrCorInfo('16-M').ec_cw_per_block := 28; gprErrCorInfo('16-M').blocks_in_g1 := 7; gprErrCorInfo('16-M').cw_in_g1 := 45; gprErrCorInfo('16-M').blocks_in_g2 := 3; gprErrCorInfo('16-M').cw_in_g2 := 46;
459 | gprErrCorInfo('16-Q').total_no_of_data_cw := 325; gprErrCorInfo('16-Q').ec_cw_per_block := 24; gprErrCorInfo('16-Q').blocks_in_g1 := 15; gprErrCorInfo('16-Q').cw_in_g1 := 19; gprErrCorInfo('16-Q').blocks_in_g2 := 2; gprErrCorInfo('16-Q').cw_in_g2 := 20;
460 | gprErrCorInfo('16-H').total_no_of_data_cw := 253; gprErrCorInfo('16-H').ec_cw_per_block := 30; gprErrCorInfo('16-H').blocks_in_g1 := 3; gprErrCorInfo('16-H').cw_in_g1 := 15; gprErrCorInfo('16-H').blocks_in_g2 := 13; gprErrCorInfo('16-H').cw_in_g2 := 16;
461 | gprErrCorInfo('17-L').total_no_of_data_cw := 647; gprErrCorInfo('17-L').ec_cw_per_block := 28; gprErrCorInfo('17-L').blocks_in_g1 := 1; gprErrCorInfo('17-L').cw_in_g1 := 107; gprErrCorInfo('17-L').blocks_in_g2 := 5; gprErrCorInfo('17-L').cw_in_g2 := 108;
462 | gprErrCorInfo('17-M').total_no_of_data_cw := 507; gprErrCorInfo('17-M').ec_cw_per_block := 28; gprErrCorInfo('17-M').blocks_in_g1 := 10; gprErrCorInfo('17-M').cw_in_g1 := 46; gprErrCorInfo('17-M').blocks_in_g2 := 1; gprErrCorInfo('17-M').cw_in_g2 := 47;
463 | gprErrCorInfo('17-Q').total_no_of_data_cw := 367; gprErrCorInfo('17-Q').ec_cw_per_block := 28; gprErrCorInfo('17-Q').blocks_in_g1 := 1; gprErrCorInfo('17-Q').cw_in_g1 := 22; gprErrCorInfo('17-Q').blocks_in_g2 := 15; gprErrCorInfo('17-Q').cw_in_g2 := 23;
464 | gprErrCorInfo('17-H').total_no_of_data_cw := 283; gprErrCorInfo('17-H').ec_cw_per_block := 28; gprErrCorInfo('17-H').blocks_in_g1 := 2; gprErrCorInfo('17-H').cw_in_g1 := 14; gprErrCorInfo('17-H').blocks_in_g2 := 17; gprErrCorInfo('17-H').cw_in_g2 := 15;
465 | gprErrCorInfo('18-L').total_no_of_data_cw := 721; gprErrCorInfo('18-L').ec_cw_per_block := 30; gprErrCorInfo('18-L').blocks_in_g1 := 5; gprErrCorInfo('18-L').cw_in_g1 := 120; gprErrCorInfo('18-L').blocks_in_g2 := 1; gprErrCorInfo('18-L').cw_in_g2 := 121;
466 | gprErrCorInfo('18-M').total_no_of_data_cw := 563; gprErrCorInfo('18-M').ec_cw_per_block := 26; gprErrCorInfo('18-M').blocks_in_g1 := 9; gprErrCorInfo('18-M').cw_in_g1 := 43; gprErrCorInfo('18-M').blocks_in_g2 := 4; gprErrCorInfo('18-M').cw_in_g2 := 44;
467 | gprErrCorInfo('18-Q').total_no_of_data_cw := 397; gprErrCorInfo('18-Q').ec_cw_per_block := 28; gprErrCorInfo('18-Q').blocks_in_g1 := 17; gprErrCorInfo('18-Q').cw_in_g1 := 22; gprErrCorInfo('18-Q').blocks_in_g2 := 1; gprErrCorInfo('18-Q').cw_in_g2 := 23;
468 | gprErrCorInfo('18-H').total_no_of_data_cw := 313; gprErrCorInfo('18-H').ec_cw_per_block := 28; gprErrCorInfo('18-H').blocks_in_g1 := 2; gprErrCorInfo('18-H').cw_in_g1 := 14; gprErrCorInfo('18-H').blocks_in_g2 := 19; gprErrCorInfo('18-H').cw_in_g2 := 15;
469 | gprErrCorInfo('19-L').total_no_of_data_cw := 795; gprErrCorInfo('19-L').ec_cw_per_block := 28; gprErrCorInfo('19-L').blocks_in_g1 := 3; gprErrCorInfo('19-L').cw_in_g1 := 113; gprErrCorInfo('19-L').blocks_in_g2 := 4; gprErrCorInfo('19-L').cw_in_g2 := 114;
470 | gprErrCorInfo('19-M').total_no_of_data_cw := 627; gprErrCorInfo('19-M').ec_cw_per_block := 26; gprErrCorInfo('19-M').blocks_in_g1 := 3; gprErrCorInfo('19-M').cw_in_g1 := 44; gprErrCorInfo('19-M').blocks_in_g2 := 11; gprErrCorInfo('19-M').cw_in_g2 := 45;
471 | gprErrCorInfo('19-Q').total_no_of_data_cw := 445; gprErrCorInfo('19-Q').ec_cw_per_block := 26; gprErrCorInfo('19-Q').blocks_in_g1 := 17; gprErrCorInfo('19-Q').cw_in_g1 := 21; gprErrCorInfo('19-Q').blocks_in_g2 := 4; gprErrCorInfo('19-Q').cw_in_g2 := 22;
472 | gprErrCorInfo('19-H').total_no_of_data_cw := 341; gprErrCorInfo('19-H').ec_cw_per_block := 26; gprErrCorInfo('19-H').blocks_in_g1 := 9; gprErrCorInfo('19-H').cw_in_g1 := 13; gprErrCorInfo('19-H').blocks_in_g2 := 16; gprErrCorInfo('19-H').cw_in_g2 := 14;
473 | gprErrCorInfo('20-L').total_no_of_data_cw := 861; gprErrCorInfo('20-L').ec_cw_per_block := 28; gprErrCorInfo('20-L').blocks_in_g1 := 3; gprErrCorInfo('20-L').cw_in_g1 := 107; gprErrCorInfo('20-L').blocks_in_g2 := 5; gprErrCorInfo('20-L').cw_in_g2 := 108;
474 | gprErrCorInfo('20-M').total_no_of_data_cw := 669; gprErrCorInfo('20-M').ec_cw_per_block := 26; gprErrCorInfo('20-M').blocks_in_g1 := 3; gprErrCorInfo('20-M').cw_in_g1 := 41; gprErrCorInfo('20-M').blocks_in_g2 := 13; gprErrCorInfo('20-M').cw_in_g2 := 42;
475 | gprErrCorInfo('20-Q').total_no_of_data_cw := 485; gprErrCorInfo('20-Q').ec_cw_per_block := 30; gprErrCorInfo('20-Q').blocks_in_g1 := 15; gprErrCorInfo('20-Q').cw_in_g1 := 24; gprErrCorInfo('20-Q').blocks_in_g2 := 5; gprErrCorInfo('20-Q').cw_in_g2 := 25;
476 | gprErrCorInfo('20-H').total_no_of_data_cw := 385; gprErrCorInfo('20-H').ec_cw_per_block := 28; gprErrCorInfo('20-H').blocks_in_g1 := 15; gprErrCorInfo('20-H').cw_in_g1 := 15; gprErrCorInfo('20-H').blocks_in_g2 := 10; gprErrCorInfo('20-H').cw_in_g2 := 16;
477 | gprErrCorInfo('21-L').total_no_of_data_cw := 932; gprErrCorInfo('21-L').ec_cw_per_block := 28; gprErrCorInfo('21-L').blocks_in_g1 := 4; gprErrCorInfo('21-L').cw_in_g1 := 116; gprErrCorInfo('21-L').blocks_in_g2 := 4; gprErrCorInfo('21-L').cw_in_g2 := 117;
478 | gprErrCorInfo('21-M').total_no_of_data_cw := 714; gprErrCorInfo('21-M').ec_cw_per_block := 26; gprErrCorInfo('21-M').blocks_in_g1 := 17; gprErrCorInfo('21-M').cw_in_g1 := 42; gprErrCorInfo('21-M').blocks_in_g2 := null; gprErrCorInfo('21-M').cw_in_g2 := null;
479 | gprErrCorInfo('21-Q').total_no_of_data_cw := 512; gprErrCorInfo('21-Q').ec_cw_per_block := 28; gprErrCorInfo('21-Q').blocks_in_g1 := 17; gprErrCorInfo('21-Q').cw_in_g1 := 22; gprErrCorInfo('21-Q').blocks_in_g2 := 6; gprErrCorInfo('21-Q').cw_in_g2 := 23;
480 | gprErrCorInfo('21-H').total_no_of_data_cw := 406; gprErrCorInfo('21-H').ec_cw_per_block := 30; gprErrCorInfo('21-H').blocks_in_g1 := 19; gprErrCorInfo('21-H').cw_in_g1 := 16; gprErrCorInfo('21-H').blocks_in_g2 := 6; gprErrCorInfo('21-H').cw_in_g2 := 17;
481 | gprErrCorInfo('22-L').total_no_of_data_cw := 1006; gprErrCorInfo('22-L').ec_cw_per_block := 28; gprErrCorInfo('22-L').blocks_in_g1 := 2; gprErrCorInfo('22-L').cw_in_g1 := 111; gprErrCorInfo('22-L').blocks_in_g2 := 7; gprErrCorInfo('22-L').cw_in_g2 := 112;
482 | gprErrCorInfo('22-M').total_no_of_data_cw := 782; gprErrCorInfo('22-M').ec_cw_per_block := 28; gprErrCorInfo('22-M').blocks_in_g1 := 17; gprErrCorInfo('22-M').cw_in_g1 := 46; gprErrCorInfo('22-M').blocks_in_g2 := null; gprErrCorInfo('22-M').cw_in_g2 := null;
483 | gprErrCorInfo('22-Q').total_no_of_data_cw := 568; gprErrCorInfo('22-Q').ec_cw_per_block := 30; gprErrCorInfo('22-Q').blocks_in_g1 := 7; gprErrCorInfo('22-Q').cw_in_g1 := 24; gprErrCorInfo('22-Q').blocks_in_g2 := 16; gprErrCorInfo('22-Q').cw_in_g2 := 25;
484 | gprErrCorInfo('22-H').total_no_of_data_cw := 442; gprErrCorInfo('22-H').ec_cw_per_block := 24; gprErrCorInfo('22-H').blocks_in_g1 := 34; gprErrCorInfo('22-H').cw_in_g1 := 13; gprErrCorInfo('22-H').blocks_in_g2 := null; gprErrCorInfo('22-H').cw_in_g2 := null;
485 | gprErrCorInfo('23-L').total_no_of_data_cw := 1094; gprErrCorInfo('23-L').ec_cw_per_block := 30; gprErrCorInfo('23-L').blocks_in_g1 := 4; gprErrCorInfo('23-L').cw_in_g1 := 121; gprErrCorInfo('23-L').blocks_in_g2 := 5; gprErrCorInfo('23-L').cw_in_g2 := 122;
486 | gprErrCorInfo('23-M').total_no_of_data_cw := 860; gprErrCorInfo('23-M').ec_cw_per_block := 28; gprErrCorInfo('23-M').blocks_in_g1 := 4; gprErrCorInfo('23-M').cw_in_g1 := 47; gprErrCorInfo('23-M').blocks_in_g2 := 14; gprErrCorInfo('23-M').cw_in_g2 := 48;
487 | gprErrCorInfo('23-Q').total_no_of_data_cw := 614; gprErrCorInfo('23-Q').ec_cw_per_block := 30; gprErrCorInfo('23-Q').blocks_in_g1 := 11; gprErrCorInfo('23-Q').cw_in_g1 := 24; gprErrCorInfo('23-Q').blocks_in_g2 := 14; gprErrCorInfo('23-Q').cw_in_g2 := 25;
488 | gprErrCorInfo('23-H').total_no_of_data_cw := 464; gprErrCorInfo('23-H').ec_cw_per_block := 30; gprErrCorInfo('23-H').blocks_in_g1 := 16; gprErrCorInfo('23-H').cw_in_g1 := 15; gprErrCorInfo('23-H').blocks_in_g2 := 14; gprErrCorInfo('23-H').cw_in_g2 := 16;
489 | gprErrCorInfo('24-L').total_no_of_data_cw := 1174; gprErrCorInfo('24-L').ec_cw_per_block := 30; gprErrCorInfo('24-L').blocks_in_g1 := 6; gprErrCorInfo('24-L').cw_in_g1 := 117; gprErrCorInfo('24-L').blocks_in_g2 := 4; gprErrCorInfo('24-L').cw_in_g2 := 118;
490 | gprErrCorInfo('24-M').total_no_of_data_cw := 914; gprErrCorInfo('24-M').ec_cw_per_block := 28; gprErrCorInfo('24-M').blocks_in_g1 := 6; gprErrCorInfo('24-M').cw_in_g1 := 45; gprErrCorInfo('24-M').blocks_in_g2 := 14; gprErrCorInfo('24-M').cw_in_g2 := 46;
491 | gprErrCorInfo('24-Q').total_no_of_data_cw := 664; gprErrCorInfo('24-Q').ec_cw_per_block := 30; gprErrCorInfo('24-Q').blocks_in_g1 := 11; gprErrCorInfo('24-Q').cw_in_g1 := 24; gprErrCorInfo('24-Q').blocks_in_g2 := 16; gprErrCorInfo('24-Q').cw_in_g2 := 25;
492 | gprErrCorInfo('24-H').total_no_of_data_cw := 514; gprErrCorInfo('24-H').ec_cw_per_block := 30; gprErrCorInfo('24-H').blocks_in_g1 := 30; gprErrCorInfo('24-H').cw_in_g1 := 16; gprErrCorInfo('24-H').blocks_in_g2 := 2; gprErrCorInfo('24-H').cw_in_g2 := 17;
493 | gprErrCorInfo('25-L').total_no_of_data_cw := 1276; gprErrCorInfo('25-L').ec_cw_per_block := 26; gprErrCorInfo('25-L').blocks_in_g1 := 8; gprErrCorInfo('25-L').cw_in_g1 := 106; gprErrCorInfo('25-L').blocks_in_g2 := 4; gprErrCorInfo('25-L').cw_in_g2 := 107;
494 | gprErrCorInfo('25-M').total_no_of_data_cw := 1000; gprErrCorInfo('25-M').ec_cw_per_block := 28; gprErrCorInfo('25-M').blocks_in_g1 := 8; gprErrCorInfo('25-M').cw_in_g1 := 47; gprErrCorInfo('25-M').blocks_in_g2 := 13; gprErrCorInfo('25-M').cw_in_g2 := 48;
495 | gprErrCorInfo('25-Q').total_no_of_data_cw := 718; gprErrCorInfo('25-Q').ec_cw_per_block := 30; gprErrCorInfo('25-Q').blocks_in_g1 := 7; gprErrCorInfo('25-Q').cw_in_g1 := 24; gprErrCorInfo('25-Q').blocks_in_g2 := 22; gprErrCorInfo('25-Q').cw_in_g2 := 25;
496 | gprErrCorInfo('25-H').total_no_of_data_cw := 538; gprErrCorInfo('25-H').ec_cw_per_block := 30; gprErrCorInfo('25-H').blocks_in_g1 := 22; gprErrCorInfo('25-H').cw_in_g1 := 15; gprErrCorInfo('25-H').blocks_in_g2 := 13; gprErrCorInfo('25-H').cw_in_g2 := 16;
497 | gprErrCorInfo('26-L').total_no_of_data_cw := 1370; gprErrCorInfo('26-L').ec_cw_per_block := 28; gprErrCorInfo('26-L').blocks_in_g1 := 10; gprErrCorInfo('26-L').cw_in_g1 := 114; gprErrCorInfo('26-L').blocks_in_g2 := 2; gprErrCorInfo('26-L').cw_in_g2 := 115;
498 | gprErrCorInfo('26-M').total_no_of_data_cw := 1062; gprErrCorInfo('26-M').ec_cw_per_block := 28; gprErrCorInfo('26-M').blocks_in_g1 := 19; gprErrCorInfo('26-M').cw_in_g1 := 46; gprErrCorInfo('26-M').blocks_in_g2 := 4; gprErrCorInfo('26-M').cw_in_g2 := 47;
499 | gprErrCorInfo('26-Q').total_no_of_data_cw := 754; gprErrCorInfo('26-Q').ec_cw_per_block := 28; gprErrCorInfo('26-Q').blocks_in_g1 := 28; gprErrCorInfo('26-Q').cw_in_g1 := 22; gprErrCorInfo('26-Q').blocks_in_g2 := 6; gprErrCorInfo('26-Q').cw_in_g2 := 23;
500 | gprErrCorInfo('26-H').total_no_of_data_cw := 596; gprErrCorInfo('26-H').ec_cw_per_block := 30; gprErrCorInfo('26-H').blocks_in_g1 := 33; gprErrCorInfo('26-H').cw_in_g1 := 16; gprErrCorInfo('26-H').blocks_in_g2 := 4; gprErrCorInfo('26-H').cw_in_g2 := 17;
501 | gprErrCorInfo('27-L').total_no_of_data_cw := 1468; gprErrCorInfo('27-L').ec_cw_per_block := 30; gprErrCorInfo('27-L').blocks_in_g1 := 8; gprErrCorInfo('27-L').cw_in_g1 := 122; gprErrCorInfo('27-L').blocks_in_g2 := 4; gprErrCorInfo('27-L').cw_in_g2 := 123;
502 | gprErrCorInfo('27-M').total_no_of_data_cw := 1128; gprErrCorInfo('27-M').ec_cw_per_block := 28; gprErrCorInfo('27-M').blocks_in_g1 := 22; gprErrCorInfo('27-M').cw_in_g1 := 45; gprErrCorInfo('27-M').blocks_in_g2 := 3; gprErrCorInfo('27-M').cw_in_g2 := 46;
503 | gprErrCorInfo('27-Q').total_no_of_data_cw := 808; gprErrCorInfo('27-Q').ec_cw_per_block := 30; gprErrCorInfo('27-Q').blocks_in_g1 := 8; gprErrCorInfo('27-Q').cw_in_g1 := 23; gprErrCorInfo('27-Q').blocks_in_g2 := 26; gprErrCorInfo('27-Q').cw_in_g2 := 24;
504 | gprErrCorInfo('27-H').total_no_of_data_cw := 628; gprErrCorInfo('27-H').ec_cw_per_block := 30; gprErrCorInfo('27-H').blocks_in_g1 := 12; gprErrCorInfo('27-H').cw_in_g1 := 15; gprErrCorInfo('27-H').blocks_in_g2 := 28; gprErrCorInfo('27-H').cw_in_g2 := 16;
505 | gprErrCorInfo('28-L').total_no_of_data_cw := 1531; gprErrCorInfo('28-L').ec_cw_per_block := 30; gprErrCorInfo('28-L').blocks_in_g1 := 3; gprErrCorInfo('28-L').cw_in_g1 := 117; gprErrCorInfo('28-L').blocks_in_g2 := 10; gprErrCorInfo('28-L').cw_in_g2 := 118;
506 | gprErrCorInfo('28-M').total_no_of_data_cw := 1193; gprErrCorInfo('28-M').ec_cw_per_block := 28; gprErrCorInfo('28-M').blocks_in_g1 := 3; gprErrCorInfo('28-M').cw_in_g1 := 45; gprErrCorInfo('28-M').blocks_in_g2 := 23; gprErrCorInfo('28-M').cw_in_g2 := 46;
507 | gprErrCorInfo('28-Q').total_no_of_data_cw := 871; gprErrCorInfo('28-Q').ec_cw_per_block := 30; gprErrCorInfo('28-Q').blocks_in_g1 := 4; gprErrCorInfo('28-Q').cw_in_g1 := 24; gprErrCorInfo('28-Q').blocks_in_g2 := 31; gprErrCorInfo('28-Q').cw_in_g2 := 25;
508 | gprErrCorInfo('28-H').total_no_of_data_cw := 661; gprErrCorInfo('28-H').ec_cw_per_block := 30; gprErrCorInfo('28-H').blocks_in_g1 := 11; gprErrCorInfo('28-H').cw_in_g1 := 15; gprErrCorInfo('28-H').blocks_in_g2 := 31; gprErrCorInfo('28-H').cw_in_g2 := 16;
509 | gprErrCorInfo('29-L').total_no_of_data_cw := 1631; gprErrCorInfo('29-L').ec_cw_per_block := 30; gprErrCorInfo('29-L').blocks_in_g1 := 7; gprErrCorInfo('29-L').cw_in_g1 := 116; gprErrCorInfo('29-L').blocks_in_g2 := 7; gprErrCorInfo('29-L').cw_in_g2 := 117;
510 | gprErrCorInfo('29-M').total_no_of_data_cw := 1267; gprErrCorInfo('29-M').ec_cw_per_block := 28; gprErrCorInfo('29-M').blocks_in_g1 := 21; gprErrCorInfo('29-M').cw_in_g1 := 45; gprErrCorInfo('29-M').blocks_in_g2 := 7; gprErrCorInfo('29-M').cw_in_g2 := 46;
511 | gprErrCorInfo('29-Q').total_no_of_data_cw := 911; gprErrCorInfo('29-Q').ec_cw_per_block := 30; gprErrCorInfo('29-Q').blocks_in_g1 := 1; gprErrCorInfo('29-Q').cw_in_g1 := 23; gprErrCorInfo('29-Q').blocks_in_g2 := 37; gprErrCorInfo('29-Q').cw_in_g2 := 24;
512 | gprErrCorInfo('29-H').total_no_of_data_cw := 701; gprErrCorInfo('29-H').ec_cw_per_block := 30; gprErrCorInfo('29-H').blocks_in_g1 := 19; gprErrCorInfo('29-H').cw_in_g1 := 15; gprErrCorInfo('29-H').blocks_in_g2 := 26; gprErrCorInfo('29-H').cw_in_g2 := 16;
513 | gprErrCorInfo('30-L').total_no_of_data_cw := 1735; gprErrCorInfo('30-L').ec_cw_per_block := 30; gprErrCorInfo('30-L').blocks_in_g1 := 5; gprErrCorInfo('30-L').cw_in_g1 := 115; gprErrCorInfo('30-L').blocks_in_g2 := 10; gprErrCorInfo('30-L').cw_in_g2 := 116;
514 | gprErrCorInfo('30-M').total_no_of_data_cw := 1373; gprErrCorInfo('30-M').ec_cw_per_block := 28; gprErrCorInfo('30-M').blocks_in_g1 := 19; gprErrCorInfo('30-M').cw_in_g1 := 47; gprErrCorInfo('30-M').blocks_in_g2 := 10; gprErrCorInfo('30-M').cw_in_g2 := 48;
515 | gprErrCorInfo('30-Q').total_no_of_data_cw := 985; gprErrCorInfo('30-Q').ec_cw_per_block := 30; gprErrCorInfo('30-Q').blocks_in_g1 := 15; gprErrCorInfo('30-Q').cw_in_g1 := 24; gprErrCorInfo('30-Q').blocks_in_g2 := 25; gprErrCorInfo('30-Q').cw_in_g2 := 25;
516 | gprErrCorInfo('30-H').total_no_of_data_cw := 745; gprErrCorInfo('30-H').ec_cw_per_block := 30; gprErrCorInfo('30-H').blocks_in_g1 := 23; gprErrCorInfo('30-H').cw_in_g1 := 15; gprErrCorInfo('30-H').blocks_in_g2 := 25; gprErrCorInfo('30-H').cw_in_g2 := 16;
517 | gprErrCorInfo('31-L').total_no_of_data_cw := 1843; gprErrCorInfo('31-L').ec_cw_per_block := 30; gprErrCorInfo('31-L').blocks_in_g1 := 13; gprErrCorInfo('31-L').cw_in_g1 := 115; gprErrCorInfo('31-L').blocks_in_g2 := 3; gprErrCorInfo('31-L').cw_in_g2 := 116;
518 | gprErrCorInfo('31-M').total_no_of_data_cw := 1455; gprErrCorInfo('31-M').ec_cw_per_block := 28; gprErrCorInfo('31-M').blocks_in_g1 := 2; gprErrCorInfo('31-M').cw_in_g1 := 46; gprErrCorInfo('31-M').blocks_in_g2 := 29; gprErrCorInfo('31-M').cw_in_g2 := 47;
519 | gprErrCorInfo('31-Q').total_no_of_data_cw := 1033; gprErrCorInfo('31-Q').ec_cw_per_block := 30; gprErrCorInfo('31-Q').blocks_in_g1 := 42; gprErrCorInfo('31-Q').cw_in_g1 := 24; gprErrCorInfo('31-Q').blocks_in_g2 := 1; gprErrCorInfo('31-Q').cw_in_g2 := 25;
520 | gprErrCorInfo('31-H').total_no_of_data_cw := 793; gprErrCorInfo('31-H').ec_cw_per_block := 30; gprErrCorInfo('31-H').blocks_in_g1 := 23; gprErrCorInfo('31-H').cw_in_g1 := 15; gprErrCorInfo('31-H').blocks_in_g2 := 28; gprErrCorInfo('31-H').cw_in_g2 := 16;
521 | gprErrCorInfo('32-L').total_no_of_data_cw := 1955; gprErrCorInfo('32-L').ec_cw_per_block := 30; gprErrCorInfo('32-L').blocks_in_g1 := 17; gprErrCorInfo('32-L').cw_in_g1 := 115; gprErrCorInfo('32-L').blocks_in_g2 := null; gprErrCorInfo('32-L').cw_in_g2 := null;
522 | gprErrCorInfo('32-M').total_no_of_data_cw := 1541; gprErrCorInfo('32-M').ec_cw_per_block := 28; gprErrCorInfo('32-M').blocks_in_g1 := 10; gprErrCorInfo('32-M').cw_in_g1 := 46; gprErrCorInfo('32-M').blocks_in_g2 := 23; gprErrCorInfo('32-M').cw_in_g2 := 47;
523 | gprErrCorInfo('32-Q').total_no_of_data_cw := 1115; gprErrCorInfo('32-Q').ec_cw_per_block := 30; gprErrCorInfo('32-Q').blocks_in_g1 := 10; gprErrCorInfo('32-Q').cw_in_g1 := 24; gprErrCorInfo('32-Q').blocks_in_g2 := 35; gprErrCorInfo('32-Q').cw_in_g2 := 25;
524 | gprErrCorInfo('32-H').total_no_of_data_cw := 845; gprErrCorInfo('32-H').ec_cw_per_block := 30; gprErrCorInfo('32-H').blocks_in_g1 := 19; gprErrCorInfo('32-H').cw_in_g1 := 15; gprErrCorInfo('32-H').blocks_in_g2 := 35; gprErrCorInfo('32-H').cw_in_g2 := 16;
525 | gprErrCorInfo('33-L').total_no_of_data_cw := 2071; gprErrCorInfo('33-L').ec_cw_per_block := 30; gprErrCorInfo('33-L').blocks_in_g1 := 17; gprErrCorInfo('33-L').cw_in_g1 := 115; gprErrCorInfo('33-L').blocks_in_g2 := 1; gprErrCorInfo('33-L').cw_in_g2 := 116;
526 | gprErrCorInfo('33-M').total_no_of_data_cw := 1631; gprErrCorInfo('33-M').ec_cw_per_block := 28; gprErrCorInfo('33-M').blocks_in_g1 := 14; gprErrCorInfo('33-M').cw_in_g1 := 46; gprErrCorInfo('33-M').blocks_in_g2 := 21; gprErrCorInfo('33-M').cw_in_g2 := 47;
527 | gprErrCorInfo('33-Q').total_no_of_data_cw := 1171; gprErrCorInfo('33-Q').ec_cw_per_block := 30; gprErrCorInfo('33-Q').blocks_in_g1 := 29; gprErrCorInfo('33-Q').cw_in_g1 := 24; gprErrCorInfo('33-Q').blocks_in_g2 := 19; gprErrCorInfo('33-Q').cw_in_g2 := 25;
528 | gprErrCorInfo('33-H').total_no_of_data_cw := 901; gprErrCorInfo('33-H').ec_cw_per_block := 30; gprErrCorInfo('33-H').blocks_in_g1 := 11; gprErrCorInfo('33-H').cw_in_g1 := 15; gprErrCorInfo('33-H').blocks_in_g2 := 46; gprErrCorInfo('33-H').cw_in_g2 := 16;
529 | gprErrCorInfo('34-L').total_no_of_data_cw := 2191; gprErrCorInfo('34-L').ec_cw_per_block := 30; gprErrCorInfo('34-L').blocks_in_g1 := 13; gprErrCorInfo('34-L').cw_in_g1 := 115; gprErrCorInfo('34-L').blocks_in_g2 := 6; gprErrCorInfo('34-L').cw_in_g2 := 116;
530 | gprErrCorInfo('34-M').total_no_of_data_cw := 1725; gprErrCorInfo('34-M').ec_cw_per_block := 28; gprErrCorInfo('34-M').blocks_in_g1 := 14; gprErrCorInfo('34-M').cw_in_g1 := 46; gprErrCorInfo('34-M').blocks_in_g2 := 23; gprErrCorInfo('34-M').cw_in_g2 := 47;
531 | gprErrCorInfo('34-Q').total_no_of_data_cw := 1231; gprErrCorInfo('34-Q').ec_cw_per_block := 30; gprErrCorInfo('34-Q').blocks_in_g1 := 44; gprErrCorInfo('34-Q').cw_in_g1 := 24; gprErrCorInfo('34-Q').blocks_in_g2 := 7; gprErrCorInfo('34-Q').cw_in_g2 := 25;
532 | gprErrCorInfo('34-H').total_no_of_data_cw := 961; gprErrCorInfo('34-H').ec_cw_per_block := 30; gprErrCorInfo('34-H').blocks_in_g1 := 59; gprErrCorInfo('34-H').cw_in_g1 := 16; gprErrCorInfo('34-H').blocks_in_g2 := 1; gprErrCorInfo('34-H').cw_in_g2 := 17;
533 | gprErrCorInfo('35-L').total_no_of_data_cw := 2306; gprErrCorInfo('35-L').ec_cw_per_block := 30; gprErrCorInfo('35-L').blocks_in_g1 := 12; gprErrCorInfo('35-L').cw_in_g1 := 121; gprErrCorInfo('35-L').blocks_in_g2 := 7; gprErrCorInfo('35-L').cw_in_g2 := 122;
534 | gprErrCorInfo('35-M').total_no_of_data_cw := 1812; gprErrCorInfo('35-M').ec_cw_per_block := 28; gprErrCorInfo('35-M').blocks_in_g1 := 12; gprErrCorInfo('35-M').cw_in_g1 := 47; gprErrCorInfo('35-M').blocks_in_g2 := 26; gprErrCorInfo('35-M').cw_in_g2 := 48;
535 | gprErrCorInfo('35-Q').total_no_of_data_cw := 1286; gprErrCorInfo('35-Q').ec_cw_per_block := 30; gprErrCorInfo('35-Q').blocks_in_g1 := 39; gprErrCorInfo('35-Q').cw_in_g1 := 24; gprErrCorInfo('35-Q').blocks_in_g2 := 14; gprErrCorInfo('35-Q').cw_in_g2 := 25;
536 | gprErrCorInfo('35-H').total_no_of_data_cw := 986; gprErrCorInfo('35-H').ec_cw_per_block := 30; gprErrCorInfo('35-H').blocks_in_g1 := 22; gprErrCorInfo('35-H').cw_in_g1 := 15; gprErrCorInfo('35-H').blocks_in_g2 := 41; gprErrCorInfo('35-H').cw_in_g2 := 16;
537 | gprErrCorInfo('36-L').total_no_of_data_cw := 2434; gprErrCorInfo('36-L').ec_cw_per_block := 30; gprErrCorInfo('36-L').blocks_in_g1 := 6; gprErrCorInfo('36-L').cw_in_g1 := 121; gprErrCorInfo('36-L').blocks_in_g2 := 14; gprErrCorInfo('36-L').cw_in_g2 := 122;
538 | gprErrCorInfo('36-M').total_no_of_data_cw := 1914; gprErrCorInfo('36-M').ec_cw_per_block := 28; gprErrCorInfo('36-M').blocks_in_g1 := 6; gprErrCorInfo('36-M').cw_in_g1 := 47; gprErrCorInfo('36-M').blocks_in_g2 := 34; gprErrCorInfo('36-M').cw_in_g2 := 48;
539 | gprErrCorInfo('36-Q').total_no_of_data_cw := 1354; gprErrCorInfo('36-Q').ec_cw_per_block := 30; gprErrCorInfo('36-Q').blocks_in_g1 := 46; gprErrCorInfo('36-Q').cw_in_g1 := 24; gprErrCorInfo('36-Q').blocks_in_g2 := 10; gprErrCorInfo('36-Q').cw_in_g2 := 25;
540 | gprErrCorInfo('36-H').total_no_of_data_cw := 1054; gprErrCorInfo('36-H').ec_cw_per_block := 30; gprErrCorInfo('36-H').blocks_in_g1 := 2; gprErrCorInfo('36-H').cw_in_g1 := 15; gprErrCorInfo('36-H').blocks_in_g2 := 64; gprErrCorInfo('36-H').cw_in_g2 := 16;
541 | gprErrCorInfo('37-L').total_no_of_data_cw := 2566; gprErrCorInfo('37-L').ec_cw_per_block := 30; gprErrCorInfo('37-L').blocks_in_g1 := 17; gprErrCorInfo('37-L').cw_in_g1 := 122; gprErrCorInfo('37-L').blocks_in_g2 := 4; gprErrCorInfo('37-L').cw_in_g2 := 123;
542 | gprErrCorInfo('37-M').total_no_of_data_cw := 1992; gprErrCorInfo('37-M').ec_cw_per_block := 28; gprErrCorInfo('37-M').blocks_in_g1 := 29; gprErrCorInfo('37-M').cw_in_g1 := 46; gprErrCorInfo('37-M').blocks_in_g2 := 14; gprErrCorInfo('37-M').cw_in_g2 := 47;
543 | gprErrCorInfo('37-Q').total_no_of_data_cw := 1426; gprErrCorInfo('37-Q').ec_cw_per_block := 30; gprErrCorInfo('37-Q').blocks_in_g1 := 49; gprErrCorInfo('37-Q').cw_in_g1 := 24; gprErrCorInfo('37-Q').blocks_in_g2 := 10; gprErrCorInfo('37-Q').cw_in_g2 := 25;
544 | gprErrCorInfo('37-H').total_no_of_data_cw := 1096; gprErrCorInfo('37-H').ec_cw_per_block := 30; gprErrCorInfo('37-H').blocks_in_g1 := 24; gprErrCorInfo('37-H').cw_in_g1 := 15; gprErrCorInfo('37-H').blocks_in_g2 := 46; gprErrCorInfo('37-H').cw_in_g2 := 16;
545 | gprErrCorInfo('38-L').total_no_of_data_cw := 2702; gprErrCorInfo('38-L').ec_cw_per_block := 30; gprErrCorInfo('38-L').blocks_in_g1 := 4; gprErrCorInfo('38-L').cw_in_g1 := 122; gprErrCorInfo('38-L').blocks_in_g2 := 18; gprErrCorInfo('38-L').cw_in_g2 := 123;
546 | gprErrCorInfo('38-M').total_no_of_data_cw := 2102; gprErrCorInfo('38-M').ec_cw_per_block := 28; gprErrCorInfo('38-M').blocks_in_g1 := 13; gprErrCorInfo('38-M').cw_in_g1 := 46; gprErrCorInfo('38-M').blocks_in_g2 := 32; gprErrCorInfo('38-M').cw_in_g2 := 47;
547 | gprErrCorInfo('38-Q').total_no_of_data_cw := 1502; gprErrCorInfo('38-Q').ec_cw_per_block := 30; gprErrCorInfo('38-Q').blocks_in_g1 := 48; gprErrCorInfo('38-Q').cw_in_g1 := 24; gprErrCorInfo('38-Q').blocks_in_g2 := 14; gprErrCorInfo('38-Q').cw_in_g2 := 25;
548 | gprErrCorInfo('38-H').total_no_of_data_cw := 1142; gprErrCorInfo('38-H').ec_cw_per_block := 30; gprErrCorInfo('38-H').blocks_in_g1 := 42; gprErrCorInfo('38-H').cw_in_g1 := 15; gprErrCorInfo('38-H').blocks_in_g2 := 32; gprErrCorInfo('38-H').cw_in_g2 := 16;
549 | gprErrCorInfo('39-L').total_no_of_data_cw := 2812; gprErrCorInfo('39-L').ec_cw_per_block := 30; gprErrCorInfo('39-L').blocks_in_g1 := 20; gprErrCorInfo('39-L').cw_in_g1 := 117; gprErrCorInfo('39-L').blocks_in_g2 := 4; gprErrCorInfo('39-L').cw_in_g2 := 118;
550 | gprErrCorInfo('39-M').total_no_of_data_cw := 2216; gprErrCorInfo('39-M').ec_cw_per_block := 28; gprErrCorInfo('39-M').blocks_in_g1 := 40; gprErrCorInfo('39-M').cw_in_g1 := 47; gprErrCorInfo('39-M').blocks_in_g2 := 7; gprErrCorInfo('39-M').cw_in_g2 := 48;
551 | gprErrCorInfo('39-Q').total_no_of_data_cw := 1582; gprErrCorInfo('39-Q').ec_cw_per_block := 30; gprErrCorInfo('39-Q').blocks_in_g1 := 43; gprErrCorInfo('39-Q').cw_in_g1 := 24; gprErrCorInfo('39-Q').blocks_in_g2 := 22; gprErrCorInfo('39-Q').cw_in_g2 := 25;
552 | gprErrCorInfo('39-H').total_no_of_data_cw := 1222; gprErrCorInfo('39-H').ec_cw_per_block := 30; gprErrCorInfo('39-H').blocks_in_g1 := 10; gprErrCorInfo('39-H').cw_in_g1 := 15; gprErrCorInfo('39-H').blocks_in_g2 := 67; gprErrCorInfo('39-H').cw_in_g2 := 16;
553 | gprErrCorInfo('40-L').total_no_of_data_cw := 2956; gprErrCorInfo('40-L').ec_cw_per_block := 30; gprErrCorInfo('40-L').blocks_in_g1 := 19; gprErrCorInfo('40-L').cw_in_g1 := 118; gprErrCorInfo('40-L').blocks_in_g2 := 6; gprErrCorInfo('40-L').cw_in_g2 := 119;
554 | gprErrCorInfo('40-M').total_no_of_data_cw := 2334; gprErrCorInfo('40-M').ec_cw_per_block := 28; gprErrCorInfo('40-M').blocks_in_g1 := 18; gprErrCorInfo('40-M').cw_in_g1 := 47; gprErrCorInfo('40-M').blocks_in_g2 := 31; gprErrCorInfo('40-M').cw_in_g2 := 48;
555 | gprErrCorInfo('40-Q').total_no_of_data_cw := 1666; gprErrCorInfo('40-Q').ec_cw_per_block := 30; gprErrCorInfo('40-Q').blocks_in_g1 := 34; gprErrCorInfo('40-Q').cw_in_g1 := 24; gprErrCorInfo('40-Q').blocks_in_g2 := 34; gprErrCorInfo('40-Q').cw_in_g2 := 25;
556 | gprErrCorInfo('40-H').total_no_of_data_cw := 1276; gprErrCorInfo('40-H').ec_cw_per_block := 30; gprErrCorInfo('40-H').blocks_in_g1 := 20; gprErrCorInfo('40-H').cw_in_g1 := 15; gprErrCorInfo('40-H').blocks_in_g2 := 61; gprErrCorInfo('40-H').cw_in_g2 := 16;
557 | END;
558 |
559 |
560 | --CALCULATION FUNC AND PROC
561 |
562 | FUNCTION f_mode_name(p_type pls_integer) RETURN varchar2 IS
563 | lcMode varchar2(50);
564 | BEGIN
565 | lcMode :=
566 | CASE p_type
567 | WHEN cNumericMode THEN 'Numeric Mode'
568 | WHEN cAlphanumericMode THEN 'Alphanumeric Mode'
569 | WHEN cByteMode THEN 'Byte Mode'
570 | WHEN cKanjiMode THEN 'Kanji mode'
571 | ELSE null
572 | END;
573 |
574 | RETURN lcMode;
575 | END;
576 |
577 |
578 |
579 | /*
580 | function returns QR code mode depending of data going to be encoded:
581 | 1 - Numeric mode (for decimal digits 0 through 9)
582 | 2 - Alphanumeric mode (specific table encoded in this function)
583 | 3 - Byte mode (ISO-8859-1 character set or UTF-8)
584 | 4 - Double-byte mode (Kanji)
585 |
586 | UTF-8 ascii values for kanji:
587 | 3000 - 303f: Japanese-style punctuation
588 | 3040 - 309f: Hiragana
589 | 30a0 - 30ff: Katakana
590 | ff00 - ff9f: Full-width Roman characters and half-width Katakana
591 | 4e00 - 9faf: CJK unified ideographs - Common and uncommon Kanji
592 | 3400 - 4dbf: CJK unified ideographs Extension A - Rare Kanji
593 |
594 | */
595 | FUNCTION f_get_mode(p_data varchar2) RETURN pls_integer IS
596 | lnType pls_integer := 0;
597 | lcChar varchar2(1 char);
598 |
599 | FUNCTION f_is_char_kanji(p_char varchar2) RETURN boolean IS
600 | lnAscii number := ascii(p_char);
601 | lbReturn boolean := false;
602 | BEGIN
603 | if
604 | lnAscii between to_number('3000', 'xxxx') and to_number('30FF', 'xxxx') or
605 | lnAscii between to_number('FF00', 'xxxx') and to_number('FF9F', 'xxxx') or
606 | lnAscii between to_number('4E00', 'xxxx') and to_number('9FAF', 'xxxx') or
607 | lnAscii between to_number('3400', 'xxxx') and to_number('4DBF', 'xxxx')
608 | then
609 | lbReturn := true;
610 | end if;
611 |
612 | RETURN lbReturn;
613 | END;
614 |
615 | BEGIN
616 | FOR t IN 1 .. length(p_data) LOOP
617 | lcChar := substr(p_data, t, 1);
618 |
619 | if instr('0123456789', lcChar) > 0 then --numeric mode (1)
620 | p_debug(f_mode_name(cNumericMode) || ': char ' || lcChar, 2);
621 | lnType := greatest(lnType, cNumericMode);
622 |
623 | elsif instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:', lcChar) > 0 then --alphanumeric mode (2)
624 | p_debug(f_mode_name(cAlphanumericMode) || ': char ' || lcChar, 2);
625 | lnType := greatest(lnType, cAlphanumericMode);
626 |
627 | elsif not f_is_char_kanji(lcChar) then --Byte mode including UTF-8 except kanji (3)
628 | p_debug(f_mode_name(cByteMode) || ': char ' || lcChar, 2);
629 | lnType := greatest(lnType, cByteMode);
630 |
631 | else --kanji mode (4)
632 | lnType := cKanjiMode;
633 |
634 | end if;
635 |
636 | END LOOP;
637 |
638 | --debug
639 | p_debug('mode for qr code: ' || f_mode_name(lnType) );
640 |
641 | RETURN lnType;
642 | END;
643 |
644 | FUNCTION f_err_cor_2_number(p_error_correction varchar2) RETURN number IS
645 | lnNumber pls_integer;
646 | BEGIN
647 | --conversion to number
648 | lnNumber := CASE p_error_correction
649 | WHEN 'L' THEN 1
650 | WHEN 'M' THEN 2
651 | WHEN 'Q' THEN 3
652 | WHEN 'H' THEN 4
653 | ELSE 0 END;
654 |
655 | --error if mode can not be determined
656 | if lnNumber = 0 then
657 | RAISE_APPLICATION_ERROR(-20000, 'unknown error correction mode!');
658 | end if;
659 |
660 | --return value
661 | RETURN lnNumber;
662 | END f_err_cor_2_number;
663 |
664 |
665 | /*
666 | 4 different indicators which are encoded into QR code
667 | */
668 | FUNCTION f_mode_indicator RETURN varchar2 IS
669 | lcMode varchar2(4);
670 | BEGIN
671 | lcMode :=
672 | CASE gpnMode
673 | WHEN cNumericMode THEN '0001'
674 | WHEN cAlphanumericMode THEN '0010'
675 | WHEN cByteMode THEN '0100'
676 | WHEN cKanjiMode THEN '1000'
677 | ELSE null
678 | END;
679 |
680 | p_debug('Mode indicator: ' || lcMode, 2);
681 |
682 | RETURN lcMode;
683 | END;
684 |
685 |
686 |
687 |
688 | /*
689 | character count indicator - final length in bits depends of mode and version
690 | */
691 | FUNCTION f_char_count_indicator(p_data varchar2) RETURN varchar2 IS
692 | lnLength pls_integer;
693 | lcIndicator varchar2(16);
694 | lnCCILength pls_integer;
695 |
696 | BEGIN
697 | --length in bytes to binary; in case of UTF-8 one char can be more than 1 byte
698 | --that's why lengthb function is used instead of length
699 | lnLength := lengthb(p_data);
700 | lcIndicator := f_integer_2_binary(lnLength);
701 |
702 | p_debug('CCI Binary: ' || lcIndicator, 2);
703 |
704 | --padding
705 | if gpnVersion <= 9 then
706 | lnCCILength :=
707 | CASE gpnMode
708 | WHEN cNumericMode THEN 10
709 | WHEN cAlphanumericMode THEN 9
710 | WHEN cByteMode THEN 8
711 | WHEN cKanjiMode THEN 8
712 | ELSE 0
713 | END;
714 | elsif gpnVersion between 10 and 26 then
715 | lnCCILength :=
716 | CASE gpnMode
717 | WHEN cNumericMode THEN 12
718 | WHEN cAlphanumericMode THEN 11
719 | WHEN cByteMode THEN 16
720 | WHEN cKanjiMode THEN 10
721 | ELSE 0
722 | END;
723 |
724 | elsif gpnVersion >= 27 then
725 | lnCCILength :=
726 | CASE gpnMode
727 | WHEN cNumericMode THEN 14
728 | WHEN cAlphanumericMode THEN 13
729 | WHEN cByteMode THEN 16
730 | WHEN cKanjiMode THEN 12
731 | ELSE 0
732 | END;
733 |
734 | end if;
735 | p_debug('Character Count Indicator length: ' || lnCCILength, 2);
736 |
737 |
738 | lcIndicator := lpad(lcIndicator, lnCCILength, '0');
739 |
740 | p_debug('Character Count Indicator: ' || lcIndicator, 2);
741 |
742 |
743 | RETURN lcIndicator;
744 | END f_char_count_indicator;
745 |
746 |
747 | /*
748 | function determins and returns a QR code version (size), which depends of 3 values:
749 | - error correction level
750 | - mode (numeric, alphanumeric, byte or double byte)
751 | - length of data
752 |
753 | Version is determined from a table, where 3 dimensions are values from previous list
754 | We are searching for a smallest value, which can contain our data (error correction level and mode are fixed)
755 |
756 | For example, for:
757 | - correction level "M"
758 | - data "HELLO TO ALL PEOPLE IN THE WORLD" (data length is 32, mode is alphanumeric)
759 | a version is 2, because for given dimensions a version 2 can contain maximal of 38 characters and we have 32 characters
760 | Version 1 can contain maximal 20 characters and it is not enough.
761 | */
762 | FUNCTION f_get_version(
763 | p_data varchar2,
764 | p_error_correction varchar2) RETURN pls_integer IS
765 |
766 | TYPE t_values IS TABLE OF varchar2(1000) INDEX BY pls_integer;
767 | lrValues t_values;
768 |
769 | TYPE t_numbers IS TABLE OF pls_integer;
770 | lrData t_numbers;
771 |
772 | lnVersion pls_integer := 0;
773 | lnLength pls_integer;
774 |
775 | lnElements pls_integer;
776 | lnPosition pls_integer;
777 |
778 |
779 | FUNCTION f_explode(
780 | p_text varchar2,
781 | p_delimiter varchar2
782 | ) RETURN t_numbers IS
783 |
784 | lrList t_numbers := t_numbers();
785 | lnCounter pls_integer := 0;
786 | lcText varchar2(32000) := p_text;
787 |
788 | BEGIN
789 | LOOP
790 | lnCounter := instr(lcText, p_delimiter);
791 |
792 | if lnCounter > 0 then
793 | lrList.extend(1);
794 | lrList(lrList.count) := substr(lcText, 1, lnCounter - 1);
795 | lcText := substr(lcText, lnCounter + length(p_delimiter));
796 | else
797 | lrList.extend(1);
798 | lrList(lrList.count) := lcText;
799 | RETURN lrList;
800 | end if;
801 |
802 | END LOOP;
803 | END f_explode;
804 |
805 | BEGIN
806 | --initial values to determine version
807 | lnLength := lengthb(p_data);
808 |
809 | /*
810 | values are separated in sets; each set has 4 values
811 | first value in set is for numeric mode, second for alphanumeric, then byte and at the end for double-byte
812 | first set is for error level "L", next set for "M", then "Q" then "H"
813 | example for version 1 (values are maximal number of characters for error level correction and mode)
814 | numeric alphanumeric byte double-byte
815 | L 41 25 17 10
816 | M 34 20 14 8
817 | Q 27 16 11 7
818 | H 17 10 7 4
819 |
820 | index for variable lrValues is version
821 | values are parsed in collection during runtime
822 | */
823 |
824 | lrValues(1) := '41,25,17,10,34,20,14,8,27,16,11,7,17,10,7,4';
825 | lrValues(2) := '77,47,32,20,63,38,26,16,48,29,20,12,34,20,14,8';
826 | lrValues(3) := '127,77,53,32,101,61,42,26,77,47,32,20,58,35,24,15';
827 | lrValues(4) := '187,114,78,48,149,90,62,38,111,67,46,28,82,50,34,21';
828 | lrValues(5) := '255,154,106,65,202,122,84,52,144,87,60,37,106,64,44,27';
829 | lrValues(6) := '322,195,134,82,255,154,106,65,178,108,74,45,139,84,58,36';
830 | lrValues(7) := '370,224,154,95,293,178,122,75,207,125,86,53,154,93,64,39';
831 | lrValues(8) := '461,279,192,118,365,221,152,93,259,157,108,66,202,122,84,52';
832 | lrValues(9) := '552,335,230,141,432,262,180,111,312,189,130,80,235,143,98,60';
833 | lrValues(10) := '652,395,271,167,513,311,213,131,364,221,151,93,288,174,119,74';
834 | lrValues(11) := '772,468,321,198,604,366,251,155,427,259,177,109,331,200,137,85';
835 | lrValues(12) := '883,535,367,226,691,419,287,177,489,296,203,125,374,227,155,96';
836 | lrValues(13) := '1022,619,425,262,796,483,331,204,580,352,241,149,427,259,177,109';
837 | lrValues(14) := '1101,667,458,282,871,528,362,223,621,376,258,159,468,283,194,120';
838 | lrValues(15) := '1250,758,520,320,991,600,412,254,703,426,292,180,530,321,220,136';
839 | lrValues(16) := '1408,854,586,361,1082,656,450,277,775,470,322,198,602,365,250,154';
840 | lrValues(17) := '1548,938,644,397,1212,734,504,310,876,531,364,224,674,408,280,173';
841 | lrValues(18) := '1725,1046,718,442,1346,816,560,345,948,574,394,243,746,452,310,191';
842 | lrValues(19) := '1903,1153,792,488,1500,909,624,384,1063,644,442,272,813,493,338,208';
843 | lrValues(20) := '2061,1249,858,528,1600,970,666,410,1159,702,482,297,919,557,382,235';
844 | lrValues(21) := '2232,1352,929,572,1708,1035,711,438,1224,742,509,314,969,587,403,248';
845 | lrValues(22) := '2409,1460,1003,618,1872,1134,779,480,1358,823,565,348,1056,640,439,270';
846 | lrValues(23) := '2620,1588,1091,672,2059,1248,857,528,1468,890,611,376,1108,672,461,284';
847 | lrValues(24) := '2812,1704,1171,721,2188,1326,911,561,1588,963,661,407,1228,744,511,315';
848 | lrValues(25) := '3057,1853,1273,784,2395,1451,997,614,1718,1041,715,440,1286,779,535,330';
849 | lrValues(26) := '3283,1990,1367,842,2544,1542,1059,652,1804,1094,751,462,1425,864,593,365';
850 | lrValues(27) := '3517,2132,1465,902,2701,1637,1125,692,1933,1172,805,496,1501,910,625,385';
851 | lrValues(28) := '3669,2223,1528,940,2857,1732,1190,732,2085,1263,868,534,1581,958,658,405';
852 | lrValues(29) := '3909,2369,1628,1002,3035,1839,1264,778,2181,1322,908,559,1677,1016,698,430';
853 | lrValues(30) := '4158,2520,1732,1066,3289,1994,1370,843,2358,1429,982,604,1782,1080,742,457';
854 | lrValues(31) := '4417,2677,1840,1132,3486,2113,1452,894,2473,1499,1030,634,1897,1150,790,486';
855 | lrValues(32) := '4686,2840,1952,1201,3693,2238,1538,947,2670,1618,1112,684,2022,1226,842,518';
856 | lrValues(33) := '4965,3009,2068,1273,3909,2369,1628,1002,2805,1700,1168,719,2157,1307,898,553';
857 | lrValues(34) := '5253,3183,2188,1347,4134,2506,1722,1060,2949,1787,1228,756,2301,1394,958,590';
858 | lrValues(35) := '5529,3351,2303,1417,4343,2632,1809,1113,3081,1867,1283,790,2361,1431,983,605';
859 | lrValues(36) := '5836,3537,2431,1496,4588,2780,1911,1176,3244,1966,1351,832,2524,1530,1051,647';
860 | lrValues(37) := '6153,3729,2563,1577,4775,2894,1989,1224,3417,2071,1423,876,2625,1591,1093,673';
861 | lrValues(38) := '6479,3927,2699,1661,5039,3054,2099,1292,3599,2181,1499,923,2735,1658,1139,701';
862 | lrValues(39) := '6743,4087,2809,1729,5313,3220,2213,1362,3791,2298,1579,972,2927,1774,1219,750';
863 | lrValues(40) := '7089,4296,2953,1817,5596,3391,2331,1435,3993,2420,1663,1024,3057,1852,1273,784';
864 |
865 |
866 | --a version depending of error correction method, mode and data length
867 | lnPosition := (f_err_cor_2_number(p_error_correction) - 1) * 4 + gpnMode;
868 |
869 | p_debug('length: ' || lnLength, 2);
870 |
871 | FOR t IN 1 .. 40 LOOP
872 | p_debug(lrValues(t), 4);
873 |
874 | /*
875 | SELECT to_number(column_value) a
876 | BULK COLLECT INTO lrData
877 | FROM XMLTABLE(lrValues(t));
878 | */
879 | lrData := f_explode(
880 | p_text => lrValues(t),
881 | p_delimiter => ','
882 | );
883 |
884 | p_debug('Value on position ' || lnPosition || ': ' || lrData(lnPosition), 2);
885 |
886 | if lrData(lnPosition) >= lnLength then
887 | lnVersion := t;
888 | EXIT;
889 | end if;
890 |
891 | END LOOP;
892 |
893 | --if version can not be determined then throw error
894 | if lnVersion = 0 then
895 | RAISE_APPLICATION_ERROR(-20000, 'Data length is too big to be encoded in one QR code.');
896 | end if;
897 |
898 | --debug
899 | p_debug('version: ' || lnVersion);
900 |
901 | RETURN lnVersion;
902 |
903 | END f_get_version;
904 |
905 |
906 | FUNCTION f_encode_data(
907 | p_data varchar2,
908 | p_error_correction varchar2) RETURN varchar2 IS
909 |
910 | lcData varchar2(32000);
911 | lnCounter pls_integer := 1;
912 | lcSub varchar2(3);
913 | lnReqNumOfBits pls_integer;
914 | lcChar varchar2(1 char);
915 |
916 | --function returns value of character in alphanumeric mode
917 | FUNCTION f_get_code(p_char varchar2) RETURN pls_integer IS
918 | lnCode pls_integer;
919 | BEGIN
920 | --0 - 9
921 | if instr('0123456789', p_char) > 0 then
922 | lnCode := to_number(p_char);
923 | elsif instr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', p_char) > 0 then
924 | lnCode := ascii(p_char) - 55;
925 | elsif p_char = ' ' then
926 | lnCode := 36;
927 | elsif p_char = '$' then
928 | lnCode := 37;
929 | elsif p_char = '%' then
930 | lnCode := 38;
931 | elsif p_char = '*' then
932 | lnCode := 39;
933 | elsif p_char = '+' then
934 | lnCode := 40;
935 | elsif p_char = '-' then
936 | lnCode := 41;
937 | elsif p_char = '.' then
938 | lnCode := 42;
939 | elsif p_char = '/' then
940 | lnCode := 43;
941 | elsif p_char = ':' then
942 | lnCode := 44;
943 | end if;
944 |
945 | RETURN lnCode;
946 | END f_get_code;
947 |
948 |
949 | BEGIN
950 | --encoded data regardless of mode always start with mode indicator and character count indicator
951 | lcData := f_mode_indicator || f_char_count_indicator(p_data);
952 |
953 | --data encoding - different for different modes
954 | if gpnMode = cNumericMode then
955 | LOOP
956 | lcSub := substr(p_data, lnCounter, 3);
957 |
958 | p_debug(lcSub, 2);
959 |
960 | if length(lcSub) = 3 then
961 | lcData := lcData || lpad(f_integer_2_binary( to_number(lcSub) ), 10, '0');
962 | elsif length(lcSub) = 2 then
963 | lcData := lcData || lpad(f_integer_2_binary( to_number(lcSub) ), 7, '0');
964 | elsif length(lcSub) = 1 then
965 | lcData := lcData || lpad(f_integer_2_binary( to_number(lcSub) ), 4, '0');
966 | end if;
967 |
968 | EXIT WHEN lnCounter >= length(p_data);
969 |
970 | lnCounter := lnCounter + 3;
971 | END LOOP;
972 |
973 | elsif gpnMode = cAlphanumericMode then
974 |
975 | LOOP
976 | lcSub := substr(p_data, lnCounter, 2);
977 |
978 | p_debug(lcSub, 2);
979 |
980 | if length(lcSub) = 2 then
981 | lcData := lcData || lpad(f_integer_2_binary( f_get_code(substr(lcSub, 1, 1)) * 45 + f_get_code(substr(lcSub, 2, 1)) ), 11, '0');
982 | elsif length(lcSub) = 1 then
983 | lcData := lcData || lpad(f_integer_2_binary( f_get_code(lcSub) ), 6, '0');
984 | end if;
985 |
986 | EXIT WHEN lnCounter >= length(p_data);
987 |
988 | lnCounter := lnCounter + 2;
989 | END LOOP;
990 |
991 | elsif gpnMode = cByteMode then
992 | FOR t IN 1 .. length(p_data) LOOP
993 | lcChar := substr(p_data, t, 1);
994 | lcData := lcData || lpad(f_integer_2_binary( ascii(lcChar) ), 8 * lengthb(lcChar), '0');
995 |
996 | END LOOP;
997 |
998 | elsif gpnMode = cKanjiMode then
999 | --TODO for Kanji mode
1000 | null;
1001 | end if;
1002 |
1003 | p_debug('Data without right padding (number of bits ' || length(lcData) || '): ' || lcData, 2);
1004 |
1005 | --terminator zeros
1006 | lnReqNumOfBits := gprErrCorInfo(gpnVersion || '-' || p_error_correction).total_no_of_data_cw * 8;
1007 | p_debug('Required number of bits: ' || lnReqNumOfBits, 2);
1008 |
1009 | p_debug('Terminator zeros to add: ' || (lnReqNumOfBits - lengthb(lcData)), 2);
1010 |
1011 | if lnReqNumOfBits - lengthb(lcData) >= 4 then
1012 | lcData := lcData || '0000';
1013 | else
1014 | lcData := rpad(lcData, lnReqNumOfBits, '0');
1015 | end if;
1016 |
1017 | p_debug('Data with right padding (number of bits ' || length(lcData) || '): ' || lcData, 2);
1018 |
1019 | --additional right padding with 0 to reach a string length multiple of 8
1020 | LOOP
1021 | EXIT WHEN length(lcData) mod 8 = 0;
1022 | lcData := lcData || '0';
1023 | p_debug('Additional right padding zeros: 0', 2);
1024 | END LOOP;
1025 |
1026 | --final filling of data with 11101100 and 00010001 alternatively until full length is reached
1027 | LOOP
1028 | EXIT WHEN length(lcData) = lnReqNumOfBits;
1029 | lcData := lcData || '11101100';
1030 | p_debug('Additional padding with: 11101100', 2);
1031 | EXIT WHEN length(lcData) = lnReqNumOfBits;
1032 | lcData := lcData || '00010001';
1033 | p_debug('Additional padding with: 00010001', 2);
1034 | END LOOP;
1035 |
1036 |
1037 | --debug
1038 | p_debug('Data (number of bits ' || length(lcData) || '): ' || lcData);
1039 |
1040 | RETURN lcData;
1041 |
1042 | END f_encode_data;
1043 |
1044 |
1045 |
1046 | FUNCTION f_final_data_with_ec(
1047 | p_encoded_data varchar2,
1048 | p_error_correction varchar2) RETURN varchar2 IS
1049 |
1050 | TYPE t_cw IS TABLE OF pls_integer;
1051 | TYPE r_block IS RECORD (cw t_cw);
1052 | TYPE t_block IS TABLE OF r_block INDEX BY varchar2(10);
1053 |
1054 | lrBlock t_block;
1055 |
1056 | lcVersionEC varchar2(10);
1057 | lcBlock varchar2(10);
1058 | lnCounter pls_integer := 1;
1059 | lcCW varchar2(8);
1060 | lnCW pls_integer;
1061 | lnGroups pls_integer;
1062 | lcDebug varchar2(10000);
1063 | lnReminderBits pls_integer := 0;
1064 |
1065 | lcResult varchar2(32000);
1066 |
1067 | FUNCTION f_blocks_in_group(p_group pls_integer) RETURN pls_integer IS
1068 | BEGIN
1069 | RETURN
1070 | CASE
1071 | WHEN p_group = 1 THEN gprErrCorInfo(lcVersionEC).blocks_in_g1
1072 | ELSE nvl(gprErrCorInfo(lcVersionEC).blocks_in_g2, 0)
1073 | END;
1074 | END;
1075 |
1076 | FUNCTION f_cw_in_group(p_group pls_integer) RETURN pls_integer IS
1077 | BEGIN
1078 | RETURN
1079 | CASE
1080 | WHEN p_group = 1 THEN gprErrCorInfo(lcVersionEC).cw_in_g1
1081 | ELSE nvl(gprErrCorInfo(lcVersionEC).cw_in_g2, 0)
1082 | END;
1083 | END;
1084 |
1085 | PROCEDURE p_add_cw_to_block(p_gb varchar2, p_cw pls_integer) IS
1086 | BEGIN
1087 | lrBlock(p_gb).cw.extend;
1088 | lrBlock(p_gb).cw(lrBlock(p_gb).cw.count) := p_cw;
1089 | END;
1090 |
1091 | PROCEDURE p_debug_collection(
1092 | p_description varchar2,
1093 | p_collection t_cw,
1094 | p_level pls_integer default 1) IS
1095 |
1096 | BEGIN
1097 | lcDebug := p_description;
1098 | FOR t IN p_collection.first .. p_collection.last LOOP
1099 | lcDebug := lcDebug || p_collection(t) || ', ';
1100 | END LOOP;
1101 | p_debug(rtrim(lcDebug, ', '), p_level);
1102 | END;
1103 |
1104 | FUNCTION f_poly_divide(p_mess_poly t_cw, p_gen_poly t_cw) RETURN t_cw IS
1105 | lrEC t_cw := t_cw();
1106 | lrDivider t_cw := t_cw();
1107 | lrResult t_cw := t_cw();
1108 |
1109 | lnAnti pls_integer;
1110 | BEGIN
1111 | --copy message polynomial to lrEC
1112 | lrEC := lrEc MULTISET UNION ALL p_mess_poly;
1113 |
1114 | --To make sure that the exponent of the lead term doesn't become too small during the division
1115 | --multiply the message polynomial by xn where n is the number of error correction codewords that are needed
1116 | --so, we extend the collection and fill those elements with 0
1117 | lrEC.extend(p_gen_poly.count - 1);
1118 | FOR t IN REVERSE lrEC.first .. lrEC.last LOOP
1119 | EXIT WHEN lrEC(t) is not null;
1120 | lrEC(t) := 0;
1121 | END LOOP;
1122 |
1123 | FOR t IN 1 .. p_mess_poly.count LOOP
1124 | p_debug('Step ' || t || ':', 2);
1125 |
1126 | if lrEC(t) > 0 then
1127 | --Lead Term of the Message Polynomial (in first cycle) or result from previous cycle
1128 | --antilog is needed for multipilcation with generator polynomial (next step)
1129 | lnAnti := gprAntiLog( lrEC(t) );
1130 | p_debug('Lead Term of the Message Polynomial: ' || lrEC(t) || ' (antiLog ' || lnAnti || ')', 2);
1131 |
1132 | --copy generator polynomial to lrDivider
1133 | lrDivider.delete;
1134 | lrDivider := lrDivider MULTISET UNION ALL p_gen_poly;
1135 |
1136 | --Multiply the Generator Polynomial by the Lead Term of the Message Polynomial
1137 | --everything is happening in antilog - generator polynomial is already in antilog
1138 | --basicly we add two antilogs
1139 | FOR p IN 1 .. lrDivider.count LOOP
1140 | lrDivider(p) := lrDivider(p) + lnAnti;
1141 | if lrDivider(p) >= 255 then
1142 | lrDivider(p) := lrDivider(p) - 255;
1143 | end if;
1144 | END LOOP;
1145 |
1146 | p_debug_collection(
1147 | 'Generator polynomial multiplied with Lead Term antiLog (in antiLog): ',
1148 | lrDivider,
1149 | 2);
1150 |
1151 | --XOR the result with the message polynomial (first cycle) or result from previous cycle
1152 | --Message or result from previous cycle is already in log, so we convert generated polynomial from previous step into log
1153 | --leading terms, which are already 0 are discarded (index is "p + t - 1")
1154 | FOR p IN 1 .. lrDivider.count LOOP
1155 | lrEC(p + t - 1) := bitxor( lrEC(p + t - 1), gprLog(lrDivider(p)) );
1156 | END LOOP;
1157 |
1158 | p_debug_collection(
1159 | 'XOR the result with the message polynomial or result from previous cycle (in Log): ',
1160 | lrEC,
1161 | 2);
1162 | else
1163 | p_debug('skipping this step and discarding next lead term 0...', 2);
1164 | end if;
1165 |
1166 | END LOOP;
1167 |
1168 | --last remaining elements are error correction codewords
1169 | FOR t IN lrEC.count - (p_gen_poly.count - 2) .. lrEC.count LOOP
1170 | lrResult.extend;
1171 | lrResult(lrResult.count) := lrEC(t);
1172 | END LOOP;
1173 |
1174 | RETURN lrResult;
1175 | END;
1176 |
1177 |
1178 | BEGIN
1179 | --Version and EC Level
1180 | lcVersionEC := gpnVersion || '-' || p_error_correction;
1181 | p_debug('Version and EC Level: ' || lcVersionEC, 2);
1182 |
1183 | --generator polynomial - init for all 13 possible options
1184 | --generator polynomial has the same structure as message polynomial (block) and so the same type is used
1185 | lrBlock('7').cw := t_cw(0, 87, 229, 146, 149, 238, 102, 21);
1186 | lrBlock('10').cw := t_cw(0, 251, 67, 46, 61, 118, 70, 64, 94, 32, 45);
1187 | lrBlock('13').cw := t_cw(0, 74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78);
1188 | lrBlock('15').cw := t_cw(0, 8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105);
1189 | lrBlock('16').cw := t_cw(0, 120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194, 225, 120);
1190 | lrBlock('17').cw := t_cw(0, 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136);
1191 | lrBlock('18').cw := t_cw(0, 215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179, 5, 98, 96, 153);
1192 | lrBlock('20').cw := t_cw(0, 17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156, 164, 212, 212, 188, 190);
1193 | lrBlock('22').cw := t_cw(0, 210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231);
1194 | lrBlock('24').cw := t_cw(0, 229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21);
1195 | lrBlock('26').cw := t_cw(0, 173, 125, 158, 2, 103, 182, 118, 17, 145, 201, 111, 28, 165, 53, 161, 21, 245, 142, 13, 102, 48, 227, 153, 145, 218, 70);
1196 | lrBlock('28').cw := t_cw(0, 168, 223, 200, 104, 224, 234, 108, 180, 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 245, 87, 42, 195, 212, 119, 242, 37, 9, 123);
1197 | lrBlock('30').cw := t_cw(0, 41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, 224, 130, 156, 37, 251, 216, 238, 40, 192, 180);
1198 |
1199 | --debug - Generator Polynomial used
1200 | p_debug_collection(
1201 | 'Generator Polynomial (' || gprErrCorInfo(lcVersionEC).ec_cw_per_block || '): ',
1202 | lrBlock(gprErrCorInfo(lcVersionEC).ec_cw_per_block).cw,
1203 | 2);
1204 |
1205 | --how many groups
1206 | lnGroups := (CASE WHEN gprErrCorInfo(lcVersionEC).blocks_in_g2 is null THEN 1 ELSE 2 END);
1207 |
1208 | --debug - number of groups and blocks in each group, number of codewords for each block in group
1209 | p_debug('Number of groups: ' || lnGroups, 2);
1210 | FOR gr IN 1 .. lnGroups LOOP
1211 | p_debug('Group ' || gr || ' - number of blocks in group: ' || f_blocks_in_group(gr), 2);
1212 | p_debug('Group ' || gr || ' - number of codewords in each block: ' || f_cw_in_group(gr), 2);
1213 | END LOOP;
1214 |
1215 | --prepare message polynomial for each group and block (G1B1, G1B2 ... G2B1, G2B2...)
1216 | FOR gr IN 1 .. lnGroups LOOP
1217 | FOR blk IN 1 .. f_blocks_in_group(gr) LOOP
1218 | --init block
1219 | lcBlock := 'G' || gr || 'B' || blk;
1220 | lrBlock(lcBlock).cw := t_cw();
1221 |
1222 | p_debug('Group ' || gr || ', block ' || blk || ' - message polynomial:', 2);
1223 |
1224 | --fill block with data codewords (codewords are converted to decimal)
1225 | FOR cw IN 1 .. f_cw_in_group(gr) LOOP
1226 | lcCW := substr(p_encoded_data, lnCounter, 8);
1227 | lnCW := bin2dec(lcCW);
1228 |
1229 | p_add_cw_to_block(lcBlock, lnCW);
1230 | p_debug('Codeword ' || cw || ': ' || lcCW || ' (' || lnCW || ')', 2);
1231 |
1232 | lnCounter := lnCounter + 8;
1233 | END LOOP;
1234 |
1235 | END LOOP;
1236 | END LOOP;
1237 |
1238 |
1239 | --calculate error correction data for each group and block (G1B1EC, G1B2EC... G2B1EC, G2B2EC...)
1240 | FOR gr IN 1 .. lnGroups LOOP
1241 | FOR blk IN 1 .. f_blocks_in_group(gr) LOOP
1242 | lrBlock('G' || gr || 'B' || blk || 'EC').cw := f_poly_divide(
1243 | lrBlock('G' || gr || 'B' || blk).cw, --message polynomial
1244 | lrBlock(gprErrCorInfo(lcVersionEC).ec_cw_per_block).cw --generator polynomial
1245 | );
1246 |
1247 | p_debug_collection(
1248 | 'Final error correction codewords for group ' || gr || ' and block ' || blk || ': ',
1249 | lrBlock('G' || gr || 'B' || blk || 'EC').cw,
1250 | 2);
1251 |
1252 | END LOOP;
1253 | END LOOP;
1254 |
1255 |
1256 | --structure final message (interleaving) - data codewords
1257 | lcDebug := 'Interleaved data codewords: ';
1258 | FOR cnt IN 1 .. greatest( f_cw_in_group(1), f_cw_in_group(2) ) LOOP
1259 | FOR gr IN 1 .. lnGroups LOOP
1260 | FOR blk IN 1 .. f_blocks_in_group(gr) LOOP
1261 |
1262 | if lrBlock('G' || gr || 'B' || blk).cw.count >= cnt then
1263 | lcResult := lcResult || lpad(f_integer_2_binary( lrBlock('G' || gr || 'B' || blk).cw(cnt) ), 8, '0');
1264 | lcDebug := lcDebug || lrBlock('G' || gr || 'B' || blk).cw(cnt) || ', ';
1265 | end if;
1266 |
1267 | END LOOP;
1268 | END LOOP;
1269 | END LOOP;
1270 | p_debug(rtrim(lcDebug, ', '), 2);
1271 |
1272 |
1273 | --structure final message (interleaving) - error correction codewords
1274 | lcDebug := 'Interleaved error correction codewords: ';
1275 | FOR cnt IN 1 .. gprErrCorInfo(lcVersionEC).ec_cw_per_block LOOP
1276 | FOR gr IN 1 .. lnGroups LOOP
1277 | FOR blk IN 1 .. f_blocks_in_group(gr) LOOP
1278 | lcResult := lcResult || lpad(f_integer_2_binary( lrBlock('G' || gr || 'B' || blk || 'EC').cw(cnt) ), 8, '0');
1279 | lcDebug := lcDebug || lrBlock('G' || gr || 'B' || blk || 'EC').cw(cnt) || ', ';
1280 | END LOOP;
1281 | END LOOP;
1282 | END LOOP;
1283 | p_debug(rtrim(lcDebug, ', '), 2);
1284 |
1285 |
1286 | --Add Remainder Bits for some QR versions, if necessary
1287 | lnReminderBits :=
1288 | CASE
1289 | WHEN gpnVersion between 2 and 6 THEN 7
1290 | WHEN gpnVersion between 21 and 27 THEN 4
1291 | WHEN gpnVersion between 14 and 20 or gpnVersion between 28 and 34 THEN 3
1292 | ELSE 0
1293 | END;
1294 | p_debug('Reminder bits: ' || lnReminderBits, 2);
1295 |
1296 | if lnReminderBits > 0 then
1297 | lcResult := rpad(lcResult, length(lcResult) + lnReminderBits, '0');
1298 | end if;
1299 |
1300 | p_debug('Final message (length ' || length(lcResult) || '): ' || lcResult);
1301 |
1302 |
1303 | RETURN lcResult;
1304 | END f_final_data_with_ec;
1305 |
1306 |
1307 |
1308 | PROCEDURE p_place_fm_in_matrix(lcData varchar2) IS
1309 |
1310 | lnColumn pls_integer;
1311 | lnRow pls_integer;
1312 | lnDirection pls_integer;
1313 |
1314 | lnCounter pls_integer;
1315 |
1316 |
1317 | PROCEDURE p_set_module(p_column pls_integer, p_row pls_integer) IS
1318 | BEGIN
1319 | if gprMatrix(p_row)(p_column) is null then
1320 | gprMatrix(p_row)(p_column) := substr(lcData, lnCounter, 1);
1321 | lnCounter := lnCounter + 1;
1322 | end if;
1323 | END;
1324 |
1325 | BEGIN
1326 | --staring values
1327 | lnColumn := f_matrix_size;
1328 |
1329 | lnRow := f_matrix_size;
1330 | lnDirection := -1;
1331 |
1332 | lnCounter := 1;
1333 |
1334 | LOOP
1335 | EXIT WHEN lnColumn < 1;
1336 |
1337 | --fill data in column
1338 | FOR t IN 1 .. f_matrix_size LOOP
1339 | p_set_module(lnColumn, lnRow);
1340 | p_set_module(lnColumn - 1, lnRow);
1341 |
1342 | lnRow := lnRow + lnDirection;
1343 | END LOOP;
1344 |
1345 | --change of direction
1346 | lnDirection := lnDirection * -1;
1347 |
1348 | --first position for next column (because the last iteration of loop breached through matrix margine)
1349 | lnRow := lnRow + lnDirection;
1350 |
1351 | --next column
1352 | lnColumn := lnColumn - 2;
1353 | --exception is vertical time pattern - if pattern is reached then column shifts to the first column on the left
1354 | if lnColumn = 7 then
1355 | lnColumn := 6;
1356 | end if;
1357 |
1358 | END LOOP;
1359 |
1360 | --debug filled matrix
1361 | p_debug('Matrix filled with final message (modules marked with dots are for format data; marked with stars are for version - those data will be filled in masking step):', 2);
1362 | p_dbms_output_matrix(gprMatrix, 2);
1363 | END;
1364 |
1365 |
1366 | PROCEDURE p_masking_format_version(p_error_correction varchar2) IS
1367 |
1368 | TYPE t_format_version IS TABLE OF varchar2(20) INDEX BY varchar2(2);
1369 |
1370 | lrFormat t_format_version;
1371 | lrVersion t_format_version;
1372 |
1373 | lnR pls_integer;
1374 | lnC pls_integer;
1375 |
1376 | PROCEDURE p_init_format_version IS
1377 | BEGIN
1378 | --init format
1379 | lrFormat('L0') := '111011111000100';
1380 | lrFormat('L1') := '111001011110011';
1381 | lrFormat('L2') := '111110110101010';
1382 | lrFormat('L3') := '111100010011101';
1383 | lrFormat('L4') := '110011000101111';
1384 | lrFormat('L5') := '110001100011000';
1385 | lrFormat('L6') := '110110001000001';
1386 | lrFormat('L7') := '110100101110110';
1387 | lrFormat('M0') := '101010000010010';
1388 | lrFormat('M1') := '101000100100101';
1389 | lrFormat('M2') := '101111001111100';
1390 | lrFormat('M3') := '101101101001011';
1391 | lrFormat('M4') := '100010111111001';
1392 | lrFormat('M5') := '100000011001110';
1393 | lrFormat('M6') := '100111110010111';
1394 | lrFormat('M7') := '100101010100000';
1395 | lrFormat('Q0') := '011010101011111';
1396 | lrFormat('Q1') := '011000001101000';
1397 | lrFormat('Q2') := '011111100110001';
1398 | lrFormat('Q3') := '011101000000110';
1399 | lrFormat('Q4') := '010010010110100';
1400 | lrFormat('Q5') := '010000110000011';
1401 | lrFormat('Q6') := '010111011011010';
1402 | lrFormat('Q7') := '010101111101101';
1403 | lrFormat('H0') := '001011010001001';
1404 | lrFormat('H1') := '001001110111110';
1405 | lrFormat('H2') := '001110011100111';
1406 | lrFormat('H3') := '001100111010000';
1407 | lrFormat('H4') := '000011101100010';
1408 | lrFormat('H5') := '000001001010101';
1409 | lrFormat('H6') := '000110100001100';
1410 | lrFormat('H7') := '000100000111011';
1411 |
1412 | --init version
1413 | lrVersion('7') := '000111110010010100';
1414 | lrVersion('8') := '001000010110111100';
1415 | lrVersion('9') := '001001101010011001';
1416 | lrVersion('10') := '001010010011010011';
1417 | lrVersion('11') := '001011101111110110';
1418 | lrVersion('12') := '001100011101100010';
1419 | lrVersion('13') := '001101100001000111';
1420 | lrVersion('14') := '001110011000001101';
1421 | lrVersion('15') := '001111100100101000';
1422 | lrVersion('16') := '010000101101111000';
1423 | lrVersion('17') := '010001010001011101';
1424 | lrVersion('18') := '010010101000010111';
1425 | lrVersion('19') := '010011010100110010';
1426 | lrVersion('20') := '010100100110100110';
1427 | lrVersion('21') := '010101011010000011';
1428 | lrVersion('22') := '010110100011001001';
1429 | lrVersion('23') := '010111011111101100';
1430 | lrVersion('24') := '011000111011000100';
1431 | lrVersion('25') := '011001000111100001';
1432 | lrVersion('26') := '011010111110101011';
1433 | lrVersion('27') := '011011000010001110';
1434 | lrVersion('28') := '011100110000011010';
1435 | lrVersion('29') := '011101001100111111';
1436 | lrVersion('30') := '011110110101110101';
1437 | lrVersion('31') := '011111001001010000';
1438 | lrVersion('32') := '100000100111010101';
1439 | lrVersion('33') := '100001011011110000';
1440 | lrVersion('34') := '100010100010111010';
1441 | lrVersion('35') := '100011011110011111';
1442 | lrVersion('36') := '100100101100001011';
1443 | lrVersion('37') := '100101010000101110';
1444 | lrVersion('38') := '100110101001100100';
1445 | lrVersion('39') := '100111010101000001';
1446 | lrVersion('40') := '101000110001101001';
1447 | END p_init_format_version;
1448 |
1449 |
1450 | PROCEDURE p_format_version(p_mask pls_integer) IS
1451 | lcFormat varchar2(20);
1452 | lcVersion varchar2(20);
1453 | lnCounter pls_integer;
1454 |
1455 | PROCEDURE p_set_module(
1456 | p_row pls_integer,
1457 | p_column pls_integer,
1458 | p_pos pls_integer,
1459 | p_format_version varchar2 --F for format and V for version
1460 | ) IS
1461 | BEGIN
1462 | --modules are reserved and values 2 and 3 are set (not 0 and 1)
1463 | gprMasking(p_mask)(p_row)(p_column) :=
1464 | (CASE WHEN substr( (CASE WHEN p_format_version = 'F' THEN lcFormat ELSE lcVersion END), p_pos, 1) = '1' THEN '3' ELSE '2' END);
1465 | END;
1466 |
1467 | BEGIN
1468 | --put format in matrix (for all 8 maskings)
1469 | lcFormat := lrFormat(p_error_correction || p_mask);
1470 | p_debug('Format for error correction ' || p_error_correction || ' and masking ' || p_mask || ': ' || lcFormat, 3);
1471 |
1472 | --top left finder
1473 | p_set_module(9, 1, 1, 'F');
1474 | p_set_module(9, 2, 2, 'F');
1475 | p_set_module(9, 3, 3, 'F');
1476 | p_set_module(9, 4, 4, 'F');
1477 | p_set_module(9, 5, 5, 'F');
1478 | p_set_module(9, 6, 6, 'F');
1479 | p_set_module(9, 8, 7, 'F');
1480 | p_set_module(9, 9, 8, 'F');
1481 | p_set_module(8, 9, 9, 'F');
1482 | p_set_module(6, 9, 10, 'F');
1483 | p_set_module(5, 9, 11, 'F');
1484 | p_set_module(4, 9, 12, 'F');
1485 | p_set_module(3, 9, 13, 'F');
1486 | p_set_module(2, 9, 14, 'F');
1487 | p_set_module(1, 9, 15, 'F');
1488 |
1489 | --lower left and top right finder
1490 | p_set_module(f_matrix_size, 9, 1, 'F');
1491 | p_set_module(f_matrix_size - 1, 9, 2, 'F');
1492 | p_set_module(f_matrix_size - 2, 9, 3, 'F');
1493 | p_set_module(f_matrix_size - 3, 9, 4, 'F');
1494 | p_set_module(f_matrix_size - 4, 9, 5, 'F');
1495 | p_set_module(f_matrix_size - 5, 9, 6, 'F');
1496 | p_set_module(f_matrix_size - 6, 9, 7, 'F');
1497 |
1498 | p_set_module(9, f_matrix_size - 7, 8, 'F');
1499 | p_set_module(9, f_matrix_size - 6, 9, 'F');
1500 | p_set_module(9, f_matrix_size - 5, 10, 'F');
1501 | p_set_module(9, f_matrix_size - 4, 11, 'F');
1502 | p_set_module(9, f_matrix_size - 3, 12, 'F');
1503 | p_set_module(9, f_matrix_size - 2, 13, 'F');
1504 | p_set_module(9, f_matrix_size - 1, 14, 'F');
1505 | p_set_module(9, f_matrix_size, 15, 'F');
1506 |
1507 |
1508 | --put version in matrix (for 7 and higher)
1509 | if gpnVersion >= 7 then
1510 | lcVersion := lrVersion(gpnVersion);
1511 | p_debug('Version (' || gpnVersion || ') for matrix: ' || lcVersion, 3);
1512 |
1513 |
1514 | lnCounter := 1;
1515 | FOR c IN REVERSE 1 .. 6 LOOP
1516 | FOR r IN 8 .. 10 LOOP
1517 | --bottom left
1518 | p_set_module(f_matrix_size - r, c, lnCounter, 'V');
1519 |
1520 | --top right
1521 | p_set_module(c, f_matrix_size - r, lnCounter, 'V');
1522 |
1523 | lnCounter := lnCounter + 1;
1524 | END LOOP;
1525 | END LOOP;
1526 |
1527 | else
1528 | p_debug('Version (' || gpnVersion || ') is not needed for matrix', 3);
1529 | end if;
1530 |
1531 |
1532 | END p_format_version;
1533 |
1534 | BEGIN
1535 | --init format and version collection
1536 | p_init_format_version;
1537 |
1538 | --copy matrix for 8 different maskings
1539 | FOR t IN 0 .. 7 LOOP
1540 | gprMasking(t) := t_column();
1541 | gprMasking(t) := gprMasking(t) MULTISET UNION ALL gprMatrix;
1542 | END LOOP;
1543 |
1544 | --mask every copy with different masking
1545 | FOR t IN 0 .. 7 LOOP
1546 |
1547 | FOR r IN 1 .. f_matrix_size LOOP
1548 | FOR c IN 1 .. f_matrix_size LOOP
1549 |
1550 | --matrix (collection) in Oracle begins with 1
1551 | lnR := r - 1;
1552 | lnC := c - 1;
1553 |
1554 | --masking is done only on data and error correction modules (matrix values 0 or 1 - other values are fixed)
1555 | if gprMasking(t)(r)(c) in ('1', '0') then
1556 |
1557 | --mask patterns
1558 | if
1559 | (t=0 and (lnR + lnC) mod 2 = 0) or
1560 | (t=1 and lnR mod 2 = 0) or
1561 | (t=2 and lnC mod 3 = 0) or
1562 | (t=3 and (lnR + lnC) mod 3 = 0) or
1563 | (t=4 and (floor(lnR / 2) + floor(lnC / 3)) mod 2 = 0) or
1564 | (t=5 and ((lnR * lnC) mod 2) + ((lnR * lnC) mod 3) = 0) or
1565 | (t=6 and (((lnR * lnC) mod 2) + ((lnR * lnC) mod 3)) mod 2 = 0) or
1566 | (t=7 and (((lnR + lnC) mod 2) + ((lnR * lnC) mod 3)) mod 2 = 0) then
1567 |
1568 | --switch black and white module
1569 | if gprMasking(t)(r)(c) = '1' then
1570 | gprMasking(t)(r)(c) := '0';
1571 | else
1572 | gprMasking(t)(r)(c) := '1';
1573 | end if;
1574 |
1575 | end if;
1576 |
1577 | end if;
1578 |
1579 | END LOOP;
1580 | END LOOP;
1581 |
1582 | p_format_version(t);
1583 |
1584 | p_debug('Mask pattern ' || t || ':', 3);
1585 | p_dbms_output_matrix(gprMasking(t), 3);
1586 | p_debug('------------------------------------------------------------------------------------------', 3);
1587 |
1588 | END LOOP;
1589 |
1590 | --reserved fields marked with 2 and 3 are not necessary any more - change them to 0 and 1
1591 | FOR t IN 0 .. 7 LOOP
1592 | FOR r IN 1 .. f_matrix_size LOOP
1593 | FOR c IN 1 .. f_matrix_size LOOP
1594 | gprMasking(t)(r)(c) := CASE gprMasking(t)(r)(c) WHEN '3' THEN '1' WHEN '2' THEN '0' ELSE gprMasking(t)(r)(c) END;
1595 | END LOOP;
1596 | END LOOP;
1597 | END LOOP;
1598 |
1599 | END p_masking_format_version;
1600 |
1601 |
1602 | PROCEDURE p_penalty_rules(p_masking_out pls_integer default null) IS
1603 | lnRule1 pls_integer;
1604 | lnRule2 pls_integer;
1605 | lnRule3 pls_integer;
1606 | lnRule4 pls_integer;
1607 |
1608 | lnCounter pls_integer;
1609 | lcPattern varchar2(11);
1610 | lnPercent pls_integer;
1611 |
1612 | lnLowestPenalty pls_integer;
1613 | lnChosenMasking pls_integer;
1614 |
1615 | lnDebugTemp pls_integer;
1616 |
1617 | BEGIN
1618 | --large initial values to be sure that first masking (0) is lower than those values
1619 | lnLowestPenalty := 100000000;
1620 | lnChosenMasking := 8;
1621 |
1622 |
1623 | --iterate through all 8 maskings, calculate penalty and find lowest penalty score
1624 | FOR t IN 0 .. 7 LOOP
1625 |
1626 | --rule 1 - five or more same-colored modules in a row (or column)
1627 | lnRule1 := 0;
1628 |
1629 | FOR r IN 1 .. f_matrix_size LOOP --horizontal direction
1630 | lnCounter := 1;
1631 | FOR c IN 2 .. f_matrix_size LOOP
1632 | if gprMasking(t)(r)(c) = gprMasking(t)(r)(c - 1) then
1633 | lnCounter := lnCounter + 1;
1634 | end if;
1635 | if gprMasking(t)(r)(c) <> gprMasking(t)(r)(c - 1) or c = f_matrix_size then
1636 | if lnCounter >= 5 then
1637 | lnRule1 := lnRule1 + 3 + (lnCounter - 5); --if 5 modules are the same color then penalty is 3 plus 1 for every additional module (4 for 6 modules...)
1638 | end if;
1639 | lnCounter := 1;
1640 | end if;
1641 | END LOOP;
1642 | END LOOP;
1643 |
1644 | lnDebugTemp := lnRule1;
1645 | p_debug('Masking ' || t || ', rule 1 - horizontal direction: ' || lnRule1, 2);
1646 |
1647 | FOR c IN 1 .. f_matrix_size LOOP --vertical direction
1648 | lnCounter := 1;
1649 | FOR r IN 2 .. f_matrix_size LOOP
1650 | if gprMasking(t)(r)(c) = gprMasking(t)(r - 1)(c) then
1651 | lnCounter := lnCounter + 1;
1652 | end if;
1653 | if gprMasking(t)(r)(c) <> gprMasking(t)(r - 1)(c) or r = f_matrix_size then
1654 | if lnCounter >= 5 then
1655 | lnRule1 := lnRule1 + 3 + (lnCounter - 5); --if 5 modules are the same color then penalty is 3 plus 1 for every additional module (4 for 6 modules...)
1656 | end if;
1657 | lnCounter := 1;
1658 | end if;
1659 | END LOOP;
1660 | END LOOP;
1661 |
1662 | p_debug('Masking ' || t || ', rule 1 - vertical direction: ' || (lnRule1 - lnDebugTemp), 2);
1663 | p_debug('Masking ' || t || ', rule 1 - sum: ' || lnRule1, 2);
1664 | p_debug(' ', 2);
1665 |
1666 |
1667 | --rule 2 - areas of the same color that are 2x2 modules
1668 | lnRule2 := 0;
1669 |
1670 | FOR r IN 1 .. f_matrix_size - 1 LOOP
1671 | FOR c IN 1 .. f_matrix_size - 1 LOOP
1672 | if
1673 | gprMasking(t)(r)(c) = gprMasking(t)(r + 1)(c) and
1674 | gprMasking(t)(r)(c) = gprMasking(t)(r)(c + 1) and
1675 | gprMasking(t)(r)(c) = gprMasking(t)(r + 1)(c + 1)
1676 | then
1677 | lnRule2 := lnRule2 + 3;
1678 | end if;
1679 | END LOOP;
1680 | END LOOP;
1681 |
1682 | p_debug('Masking ' || t || ', rule 2 - sum: ' || lnRule2, 2);
1683 | p_debug(' ', 2);
1684 |
1685 |
1686 | --rule 3 - patterns of dark-light-dark-dark-dark-light-dark that have four light modules on either side (10111010000 or 00001011101)
1687 | lnRule3 := 0;
1688 |
1689 | FOR r IN 1 .. f_matrix_size LOOP --horizontal direction
1690 | FOR c IN 1 .. f_matrix_size - 10 LOOP
1691 | lcPattern := null;
1692 | FOR p IN 0 .. 10 LOOP
1693 | lcPattern := lcPattern || gprMasking(t)(r)(c + p);
1694 | END LOOP;
1695 |
1696 | if lcPattern in ('10111010000', '00001011101') then
1697 | p_debug(lcPattern || ' (horizontal) found in row ' || r || ' and column ' || c, 3);
1698 | lnRule3 := lnRule3 + 40;
1699 | end if;
1700 | END LOOP;
1701 | END LOOP;
1702 |
1703 | lnDebugTemp := lnRule3;
1704 | p_debug('Masking ' || t || ', rule 3 - horizontal direction: ' || lnRule3, 2);
1705 |
1706 | FOR c IN 1 .. f_matrix_size LOOP --horizontal direction
1707 | FOR r IN 1 .. f_matrix_size - 10 LOOP
1708 | lcPattern := null;
1709 | FOR p IN 0 .. 10 LOOP
1710 | lcPattern := lcPattern || gprMasking(t)(r + p)(c);
1711 | END LOOP;
1712 |
1713 | if lcPattern in ('10111010000', '00001011101') then
1714 | p_debug(lcPattern || ' (vertical) found in row ' || r || ' and column ' || c, 3);
1715 | lnRule3 := lnRule3 + 40;
1716 | end if;
1717 | END LOOP;
1718 | END LOOP;
1719 |
1720 | p_debug('Masking ' || t || ', rule 3 - vertical direction: ' || (lnRule3 - lnDebugTemp), 2);
1721 | p_debug('Masking ' || t || ', rule 3 - sum: ' || lnRule3, 2);
1722 | p_debug(' ', 2);
1723 |
1724 |
1725 | --rule 4 - ratio of light modules to dark modules
1726 | lnCounter := 0; --count dark modules
1727 | FOR r IN 1 .. f_matrix_size LOOP
1728 | FOR c IN 1 .. f_matrix_size LOOP
1729 | if gprMasking(t)(r)(c) = '1' then
1730 | lnCounter := lnCounter + 1;
1731 | end if;
1732 | END LOOP;
1733 | END LOOP;
1734 |
1735 | lnPercent := trim(lnCounter * 100 / (f_matrix_size * f_matrix_size)); --calculate percent of dark modules
1736 |
1737 | p_debug('Masking ' || t || ', rule 4 - total number of modules: ' || (f_matrix_size * f_matrix_size), 2);
1738 | p_debug('Masking ' || t || ', rule 4 - dark modules: ' || lnCounter, 2);
1739 | p_debug('Masking ' || t || ', rule 4 - % of dark modules: ' || lnPercent, 2);
1740 |
1741 | LOOP --find lower multiple of 5
1742 | EXIT WHEN lnPercent mod 5 = 0;
1743 | lnPercent := lnPercent - 1;
1744 | END LOOP;
1745 |
1746 | lnRule4 := least( --subtract 50 from lower and upper multiple of 5; take absolute value; use smallest value; multiply with 10
1747 | abs(lnPercent - 50) / 5,
1748 | abs(lnPercent + 5 - 50) / 5) * 10;
1749 |
1750 | p_debug('Masking ' || t || ', rule 4 - value: ' || lnRule4, 2);
1751 | p_debug(' ', 2);
1752 |
1753 |
1754 | p_debug('Masking ' || t || ', final penalty value: ' || (lnRule1 + lnRule2 + lnRule3 + lnRule4), 2);
1755 | p_debug('-----------------------------------------', 2);
1756 |
1757 | --check if penalty for current masking is lowest
1758 | if (lnRule1 + lnRule2 + lnRule3 + lnRule4) < lnLowestPenalty then
1759 | lnLowestPenalty := (lnRule1 + lnRule2 + lnRule3 + lnRule4);
1760 | lnChosenMasking := t;
1761 | end if;
1762 |
1763 | END LOOP;
1764 |
1765 | p_debug('Masking ' || lnChosenMasking || ' has lowest penalty of ' || lnLowestPenalty || ' and will be used for QR code matrix.', 2);
1766 |
1767 | --copy the best masking into original matrix and use it as result of QR code calculation
1768 | --in case of debugging and selected masking output - use this value instead calculated and make an output
1769 | gprMatrix.delete;
1770 | gprMatrix := gprMatrix MULTISET UNION ALL gprMasking( nvl(p_masking_out, lnChosenMasking) );
1771 |
1772 | END p_penalty_rules;
1773 |
1774 |
1775 |
1776 | PROCEDURE p_generate_qr(
1777 | p_data varchar2,
1778 | p_error_correction varchar2,
1779 | p_debug boolean default false,
1780 | p_debug_level pls_integer default 1,
1781 | p_masking_out pls_integer default null
1782 | ) IS
1783 |
1784 | lcData varchar2(32000);
1785 | lcFinal varchar2(32000);
1786 |
1787 | BEGIN
1788 | --global variables and tables, which has the same values during QR code generation
1789 | gpbDebug := p_debug;
1790 | gpnDebugLevel := p_debug_level;
1791 |
1792 | gpnMode := f_get_mode(p_data);
1793 | gpnVersion := f_get_version(p_data, p_error_correction);
1794 |
1795 | p_fill_err_cor;
1796 | p_fill_log_antilog;
1797 |
1798 | --init matrix collection and fill static elements
1799 | --gpnVersion := 14; --only for debugging
1800 | p_init_matrix;
1801 |
1802 | --OPERATIONAL PART
1803 |
1804 | --encoded data with all parts (terminal zeros, padding bytes...)
1805 | lcData := f_encode_data(p_data, p_error_correction);
1806 |
1807 | --final structured message (data plus error correction)
1808 | lcFinal := f_final_data_with_ec(lcData, p_error_correction);
1809 |
1810 | --place final message in matrix
1811 | p_place_fm_in_matrix(lcFinal);
1812 |
1813 | --masking; format and version info
1814 | p_masking_format_version(p_error_correction);
1815 |
1816 | --Four Penalty Rules - choose which masking is the easiest to read and copy that masking in matrix variable
1817 | p_penalty_rules(p_masking_out);
1818 |
1819 |
1820 | END p_generate_qr;
1821 |
1822 |
1823 | FUNCTION f_matrix_2_vc2 RETURN varchar2 IS
1824 | lcQR varchar2(32727);
1825 | BEGIN
1826 | FOR t IN 1 .. gprMatrix.count LOOP
1827 | FOR p IN 1 .. gprMatrix.count LOOP
1828 | lcQR := lcQR || nvl(gprMatrix(t)(p), 'X');
1829 | END LOOP;
1830 | lcQR := lcQR || chr(10);
1831 | END LOOP;
1832 |
1833 | RETURN lcQR;
1834 | END;
1835 |
1836 |
1837 |
1838 |
1839 |
1840 |
1841 | PROCEDURE p_generate_qr_data(
1842 | p_data varchar2, --data going to be encoded into QR code
1843 | p_error_correction varchar2, --L, M, Q or H (see bellow)
1844 | p_qr OUT NOCOPY varchar2, --generated QR code data in format row || newline (chr 10) || row || newline...; 1 for black module, 0 for white
1845 | p_matrix_size OUT pls_integer --matrix size in modules (21, 25, 29...)
1846 | ) IS
1847 |
1848 | BEGIN
1849 | --generate matrix
1850 | p_generate_qr(
1851 | p_data => p_data,
1852 | p_error_correction => p_error_correction,
1853 | p_debug => false,
1854 | p_debug_level => 1);
1855 |
1856 | --convert matrix to vc2 (output)
1857 | p_qr := f_matrix_2_vc2;
1858 |
1859 | --matrix size
1860 | p_matrix_size := f_matrix_size;
1861 |
1862 | END p_generate_qr_data;
1863 |
1864 |
1865 | PROCEDURE p_qr_debug(
1866 | p_data varchar2, --data going to be encoded into QR code
1867 | p_error_correction varchar2, --L, M, Q or H (see bellow)
1868 | p_debug boolean default true, --should DBMS OUTPUT be printed
1869 | p_debug_level pls_integer default 1, --debug level (1, 2, 3...) - details to be printed in debug output
1870 | p_masking_out pls_integer default null,
1871 | p_qr OUT NOCOPY varchar2,
1872 | p_matrix_size OUT pls_integer
1873 | ) IS
1874 |
1875 | BEGIN
1876 | --generate matrix
1877 | p_generate_qr(
1878 | p_data => p_data,
1879 | p_error_correction => p_error_correction,
1880 | p_debug => p_debug,
1881 | p_debug_level => p_debug_level,
1882 | p_masking_out => p_masking_out);
1883 |
1884 | --convert matrix to debug form
1885 | p_qr := f_matrix_2_vc2;
1886 |
1887 | --matrix size
1888 | p_matrix_size := f_matrix_size;
1889 |
1890 | END p_qr_debug;
1891 |
1892 |
1893 |
1894 | FUNCTION f_qr_as_html_table(
1895 | p_data varchar2, --data going to be encoded into QR code
1896 | p_error_correction varchar2, --L, M, Q or H
1897 | p_module_size_in_px pls_integer default 8, --module size in pixels
1898 | p_margines boolean default false --margines around QR code (4 modules)
1899 | ) RETURN clob IS
1900 |
1901 | lcQR varchar2(32727);
1902 | lnMatrixSize pls_integer;
1903 | lcClob clob;
1904 |
1905 | PROCEDURE p_add_clob(lcText varchar2) IS
1906 | BEGIN
1907 | lcClob := lcClob || lcText || chr(10);
1908 | END;
1909 |
1910 | BEGIN
1911 | if p_data is null then
1912 | lcClob := 'no data to display.';
1913 | RETURN lcClob;
1914 | end if;
1915 |
1916 |
1917 | p_generate_qr_data(
1918 | p_data => p_data,
1919 | p_error_correction => p_error_correction,
1920 | p_qr => lcQR,
1921 | p_matrix_size => lnMatrixSize
1922 | );
1923 |
1924 | p_add_clob('
| '); 1948 | END LOOP; 1949 | end if; 1950 | 1951 | --modules in row 1952 | FOR p IN 1 .. lnMatrixSize LOOP 1953 | 1954 | p_add_clob(' | '); 1960 | 1961 | END LOOP; 1962 | 1963 | --right margine - 4 modules 1964 | if p_margines then 1965 | FOR z in 1 .. 4 LOOP 1966 | p_add_clob(' | '); 1967 | END LOOP; 1968 | end if; 1969 | 1970 | p_add_clob(' |