semacode 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +132 -0
- data/ext/extconf.rb +3 -0
- data/ext/iec16022ecc200.c +939 -0
- data/ext/iec16022ecc200.h +27 -0
- data/ext/reedsol.c +170 -0
- data/ext/reedsol.h +5 -0
- data/ext/semacode.c +359 -0
- data/ext/semacode.h +28 -0
- data/tests/test.rb +91 -0
- metadata +62 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
// IEC16022 bar code generation library
|
2
|
+
// Adrian Kennard, Andrews & Arnold Ltd
|
3
|
+
// with help from Cliff Hones on the RS coding
|
4
|
+
//
|
5
|
+
// Revision 1.3 2004/09/09 07:45:09 cvs
|
6
|
+
// Added change history to source files
|
7
|
+
// Added "info" type to IEC16022
|
8
|
+
// Added exact size checking shortcodes on encoding generation for iec16022
|
9
|
+
//
|
10
|
+
|
11
|
+
// Main encoding function
|
12
|
+
// Returns the grid (malloced) containing the matrix. L corner at 0,0.
|
13
|
+
// Takes suggested size in *Wptr, *Hptr, or 0,0. Fills in actual size.
|
14
|
+
// Takes barcodelen and barcode to be encoded
|
15
|
+
// Note, if *encodingptr is null, then fills with auto picked (malloced) encoding
|
16
|
+
// If lenp not null, then the length of encoded data before any final unlatch or pad is stored
|
17
|
+
// If maxp not null, then the max storage of this size code is stored
|
18
|
+
// If eccp not null, then the number of ecc bytes used in this size is stored
|
19
|
+
// Returns 0 on error (writes to stderr with details).
|
20
|
+
|
21
|
+
#define MAXBARCODE 3116
|
22
|
+
|
23
|
+
unsigned char *
|
24
|
+
iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsigned char *barcode, int *lenp,int *maxp,int *eccp);
|
25
|
+
|
26
|
+
|
27
|
+
|
data/ext/reedsol.c
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
// reedsol.c
|
2
|
+
//
|
3
|
+
// This is a simple Reed-Solomon encoder
|
4
|
+
// (C) Cliff Hones 2004
|
5
|
+
//
|
6
|
+
// It is not written with high efficiency in mind, so is probably
|
7
|
+
// not suitable for real-time encoding. The aim was to keep it
|
8
|
+
// simple, general and clear.
|
9
|
+
//
|
10
|
+
// <Some notes on the theory and implementation need to be added here>
|
11
|
+
|
12
|
+
// Usage:
|
13
|
+
// First call rs_init_gf(poly) to set up the Galois Field parameters.
|
14
|
+
// Then call rs_init_code(size, index) to set the encoding size
|
15
|
+
// Then call rs_encode(datasize, data, out) to encode the data.
|
16
|
+
//
|
17
|
+
// These can be called repeatedly as required - but note that
|
18
|
+
// rs_init_code must be called following any rs_init_gf call.
|
19
|
+
//
|
20
|
+
// If the parameters are fixed, some of the statics below can be
|
21
|
+
// replaced with constants in the obvious way, and additionally
|
22
|
+
// malloc/free can be avoided by using static arrays of a suitable
|
23
|
+
// size.
|
24
|
+
|
25
|
+
#include <stdio.h> // only needed for debug (main)
|
26
|
+
#include <stdlib.h> // only needed for malloc/free
|
27
|
+
|
28
|
+
static int gfpoly;
|
29
|
+
static int symsize; // in bits
|
30
|
+
static int logmod; // 2**symsize - 1
|
31
|
+
static int rlen;
|
32
|
+
|
33
|
+
static int *log = NULL,
|
34
|
+
*alog = NULL,
|
35
|
+
*rspoly = NULL;
|
36
|
+
|
37
|
+
// rs_init_gf(poly) initialises the parameters for the Galois Field.
|
38
|
+
// The symbol size is determined from the highest bit set in poly
|
39
|
+
// This implementation will support sizes up to 30 bits (though that
|
40
|
+
// will result in very large log/antilog tables) - bit sizes of
|
41
|
+
// 8 or 4 are typical
|
42
|
+
//
|
43
|
+
// The poly is the bit pattern representing the GF characteristic
|
44
|
+
// polynomial. e.g. for ECC200 (8-bit symbols) the polynomial is
|
45
|
+
// a**8 + a**5 + a**3 + a**2 + 1, which translates to 0x12d.
|
46
|
+
|
47
|
+
void
|
48
|
+
rs_init_gf (int poly)
|
49
|
+
{
|
50
|
+
int m,
|
51
|
+
b,
|
52
|
+
p,
|
53
|
+
v;
|
54
|
+
|
55
|
+
// Return storage from previous setup
|
56
|
+
if (log)
|
57
|
+
{
|
58
|
+
free (log);
|
59
|
+
free (alog);
|
60
|
+
free (rspoly);
|
61
|
+
rspoly = NULL;
|
62
|
+
}
|
63
|
+
// Find the top bit, and hence the symbol size
|
64
|
+
for (b = 1, m = 0; b <= poly; b <<= 1)
|
65
|
+
m++;
|
66
|
+
b >>= 1;
|
67
|
+
m--;
|
68
|
+
gfpoly = poly;
|
69
|
+
symsize = m;
|
70
|
+
|
71
|
+
// Calculate the log/alog tables
|
72
|
+
logmod = (1 << m) - 1;
|
73
|
+
log = (int *) malloc (sizeof (int) * (logmod + 1));
|
74
|
+
alog = (int *) malloc (sizeof (int) * logmod);
|
75
|
+
|
76
|
+
for (p = 1, v = 0; v < logmod; v++)
|
77
|
+
{
|
78
|
+
alog[v] = p;
|
79
|
+
log[p] = v;
|
80
|
+
p <<= 1;
|
81
|
+
if (p & b)
|
82
|
+
p ^= poly;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
// rs_init_code(nsym, index) initialises the Reed-Solomon encoder
|
87
|
+
// nsym is the number of symbols to be generated (to be appended
|
88
|
+
// to the input data). index is usually 1 - it is the index of
|
89
|
+
// the constant in the first term (i) of the RS generator polynomial:
|
90
|
+
// (x + 2**i)*(x + 2**(i+1))*... [nsym terms]
|
91
|
+
// For ECC200, index is 1.
|
92
|
+
|
93
|
+
void
|
94
|
+
rs_init_code (int nsym, int index)
|
95
|
+
{
|
96
|
+
int i,
|
97
|
+
k;
|
98
|
+
|
99
|
+
if (rspoly)
|
100
|
+
free (rspoly);
|
101
|
+
rspoly = (int *) malloc (sizeof (int) * (nsym + 1));
|
102
|
+
|
103
|
+
rlen = nsym;
|
104
|
+
|
105
|
+
rspoly[0] = 1;
|
106
|
+
for (i = 1; i <= nsym; i++)
|
107
|
+
{
|
108
|
+
rspoly[i] = 1;
|
109
|
+
for (k = i - 1; k > 0; k--)
|
110
|
+
{
|
111
|
+
if (rspoly[k])
|
112
|
+
rspoly[k] = alog[(log[rspoly[k]] + index) % logmod];
|
113
|
+
rspoly[k] ^= rspoly[k - 1];
|
114
|
+
}
|
115
|
+
rspoly[0] = alog[(log[rspoly[0]] + index) % logmod];
|
116
|
+
index++;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
// Note that the following uses byte arrays, so is only suitable for
|
121
|
+
// symbol sizes up to 8 bits. Just change the data type of data and res
|
122
|
+
// to unsigned int * for larger symbols.
|
123
|
+
|
124
|
+
void
|
125
|
+
rs_encode (int len, unsigned char *data, unsigned char *res)
|
126
|
+
{
|
127
|
+
int i,
|
128
|
+
k,
|
129
|
+
m;
|
130
|
+
for (i = 0; i < rlen; i++)
|
131
|
+
res[i] = 0;
|
132
|
+
for (i = 0; i < len; i++)
|
133
|
+
{
|
134
|
+
m = res[rlen - 1] ^ data[i];
|
135
|
+
for (k = rlen - 1; k > 0; k--)
|
136
|
+
{
|
137
|
+
if (m && rspoly[k])
|
138
|
+
res[k] = res[k - 1] ^ alog[(log[m] + log[rspoly[k]]) % logmod];
|
139
|
+
else
|
140
|
+
res[k] = res[k - 1];
|
141
|
+
}
|
142
|
+
if (m && rspoly[0])
|
143
|
+
res[0] = alog[(log[m] + log[rspoly[0]]) % logmod];
|
144
|
+
else
|
145
|
+
res[0] = 0;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
#ifndef LIB
|
150
|
+
// The following tests the routines with the ISO/IEC 16022 Annexe R data
|
151
|
+
int
|
152
|
+
main (void)
|
153
|
+
{
|
154
|
+
register int i;
|
155
|
+
|
156
|
+
unsigned char data[9] = { 142, 164, 186 };
|
157
|
+
unsigned char out[5];
|
158
|
+
|
159
|
+
rs_init_gf (0x12d);
|
160
|
+
rs_init_code (5, 1);
|
161
|
+
|
162
|
+
rs_encode (3, data, out);
|
163
|
+
|
164
|
+
printf ("Result of Annexe R encoding:\n");
|
165
|
+
for (i = 4; i >= 0; i--)
|
166
|
+
printf (" %d\n", out[i]);
|
167
|
+
|
168
|
+
return 0;
|
169
|
+
}
|
170
|
+
#endif
|
data/ext/reedsol.h
ADDED
data/ext/semacode.c
ADDED
@@ -0,0 +1,359 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
== Introduction
|
4
|
+
|
5
|
+
This Ruby extension implements a DataMatrix encoder for Ruby. It is
|
6
|
+
typically used to create semacodes, which are barcodes, that contain URLs.
|
7
|
+
This encoder does not create image files or visual representations of the
|
8
|
+
semacode. This is because it can be used for more than creating images, such
|
9
|
+
as rendering semacodes to HTML, SVG, PDF or even stored in a database or
|
10
|
+
file for later use.
|
11
|
+
|
12
|
+
Author:: Guido Sohne (mailto:guido@sohne.net)
|
13
|
+
Copyright:: Copyright (c) 2007 Guido Sohne
|
14
|
+
License:: GNU GPL version 2, available from http://www.gnu.org
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include "ruby.h"
|
18
|
+
#include "semacode.h"
|
19
|
+
|
20
|
+
/*
|
21
|
+
|
22
|
+
Internal function that encodes a string of given length, storing
|
23
|
+
the encoded result into an internal, private data structure. This
|
24
|
+
structure is consulted for any operations, such as to get the
|
25
|
+
semacode dimensions. It deallocates any previous data before
|
26
|
+
generating a new encoding.
|
27
|
+
|
28
|
+
Due to a bug in the underlying encoder, we do two things
|
29
|
+
|
30
|
+
* append a space character before encoding, to get around
|
31
|
+
an off by one error lurking in the C code
|
32
|
+
|
33
|
+
* manually select the best barcode dimensions, to avoid
|
34
|
+
an encoder bug where sometimes no suitable encoding would
|
35
|
+
be found
|
36
|
+
|
37
|
+
*/
|
38
|
+
semacode_t*
|
39
|
+
encode_string(semacode_t *semacode, int message_length, char *message)
|
40
|
+
{
|
41
|
+
/* deallocate if exists already */
|
42
|
+
if(semacode !=NULL && semacode->data != NULL)
|
43
|
+
free(semacode->data);
|
44
|
+
|
45
|
+
bzero(semacode, sizeof(semacode_t));
|
46
|
+
|
47
|
+
// work around encoding bug by appending an extra character.
|
48
|
+
strcat(message, " ");
|
49
|
+
message_length++;
|
50
|
+
|
51
|
+
// choose the best grid that will hold our message
|
52
|
+
iec16022init(&semacode->width, &semacode->height, message);
|
53
|
+
|
54
|
+
// encode the actual data
|
55
|
+
semacode->data = (char *) iec16022ecc200(
|
56
|
+
&semacode->width,
|
57
|
+
&semacode->height,
|
58
|
+
NULL,
|
59
|
+
message_length,
|
60
|
+
(unsigned char *) message,
|
61
|
+
&semacode->raw_encoded_length,
|
62
|
+
&semacode->symbol_capacity,
|
63
|
+
&semacode->ecc_bytes);
|
64
|
+
|
65
|
+
return semacode;
|
66
|
+
}
|
67
|
+
|
68
|
+
/* our module and class, respectively */
|
69
|
+
|
70
|
+
static VALUE rb_mSemacode;
|
71
|
+
static VALUE rb_cEncoder;
|
72
|
+
|
73
|
+
static void
|
74
|
+
semacode_mark(semacode_t *semacode)
|
75
|
+
{
|
76
|
+
/* need this if we ever hold any other Ruby objects. so let's not go there. */
|
77
|
+
}
|
78
|
+
|
79
|
+
static void
|
80
|
+
semacode_free(semacode_t *semacode)
|
81
|
+
{
|
82
|
+
if(semacode != NULL) {
|
83
|
+
if(semacode->data != NULL)
|
84
|
+
free(semacode->data);
|
85
|
+
bzero(semacode, sizeof(semacode));
|
86
|
+
free(semacode);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
static VALUE
|
91
|
+
semacode_allocate(VALUE klass)
|
92
|
+
{
|
93
|
+
semacode_t *semacode;
|
94
|
+
return Data_Make_Struct(klass, semacode_t, semacode_mark, semacode_free, semacode);
|
95
|
+
}
|
96
|
+
|
97
|
+
/*
|
98
|
+
Initialize the semacode. This function is called after a semaode is
|
99
|
+
created. Ruby objects are created using a new method, and then initialized
|
100
|
+
via the 'initialize' method once they have been allocated.
|
101
|
+
|
102
|
+
The initializer takes a single argument, which can be anything that
|
103
|
+
responds to the 'to_s' method - that is, anything string like.
|
104
|
+
|
105
|
+
The string in the argument is encoded and the semacode is returned
|
106
|
+
initialized and ready for use.
|
107
|
+
|
108
|
+
*/
|
109
|
+
static VALUE
|
110
|
+
semacode_init(VALUE self, VALUE message)
|
111
|
+
{
|
112
|
+
semacode_t *semacode;
|
113
|
+
|
114
|
+
if (!rb_respond_to(message, rb_intern ("to_s")))
|
115
|
+
rb_raise(rb_eRuntimeError, "target must respond to 'to_s'");
|
116
|
+
|
117
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
118
|
+
encode_string(semacode, StringValueLen(message), StringValuePtr(message));
|
119
|
+
|
120
|
+
return self;
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
This function turns the raw output from an encoding into a more
|
125
|
+
friendly format organized by rows and columns.
|
126
|
+
|
127
|
+
It returns the semacode matrix as an array of arrays of boolean. The
|
128
|
+
first element in the array is the top row, the last is the bottom row.
|
129
|
+
|
130
|
+
Each row is also an array, containing boolean values. The length of each
|
131
|
+
row is the same as the semacode width, and the number of rows is the same
|
132
|
+
as the semacode height.
|
133
|
+
|
134
|
+
*/
|
135
|
+
static VALUE
|
136
|
+
semacode_grid(semacode_t *semacode)
|
137
|
+
{
|
138
|
+
int w = semacode->width;
|
139
|
+
int h = semacode->height;
|
140
|
+
|
141
|
+
VALUE ret = rb_ary_new2(h);
|
142
|
+
|
143
|
+
int x, y;
|
144
|
+
for (y = h - 1; y >= 0; y--) {
|
145
|
+
VALUE ary = rb_ary_new2(w);
|
146
|
+
for (x = 0; x < w; x++) {
|
147
|
+
if(semacode->data[y * w + x])
|
148
|
+
rb_ary_push(ary, Qtrue);
|
149
|
+
else
|
150
|
+
rb_ary_push(ary, Qfalse);
|
151
|
+
}
|
152
|
+
rb_ary_push(ret, ary);
|
153
|
+
}
|
154
|
+
|
155
|
+
return ret;
|
156
|
+
}
|
157
|
+
|
158
|
+
/*
|
159
|
+
This function turns the raw output from an encoding into a string
|
160
|
+
representation.
|
161
|
+
|
162
|
+
It returns the semacode matrix as a comma-separated list of character
|
163
|
+
vectors (sequence of characters). The top row is the first vector and
|
164
|
+
the bottow row is the last vector.
|
165
|
+
|
166
|
+
Each vector is a sequence of characters, either '1' or '0', to represent
|
167
|
+
the bits of the semacode pattern. The length of a vector is the semacode
|
168
|
+
width, and the number of vectors is the same as the semacode height.
|
169
|
+
|
170
|
+
*/
|
171
|
+
static VALUE
|
172
|
+
semacode_to_s(VALUE self)
|
173
|
+
{
|
174
|
+
semacode_t *semacode;
|
175
|
+
VALUE str;
|
176
|
+
int x, y;
|
177
|
+
int w, h;
|
178
|
+
|
179
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
180
|
+
|
181
|
+
if(semacode == NULL || semacode->data == NULL)
|
182
|
+
return Qnil;
|
183
|
+
|
184
|
+
w = semacode->width;
|
185
|
+
h = semacode->height;
|
186
|
+
|
187
|
+
str = rb_str_new2("");
|
188
|
+
|
189
|
+
for (y = h - 1; y >= 0; y--) {
|
190
|
+
for (x = 0; x < w; x++) {
|
191
|
+
if(semacode->data[y * w + x])
|
192
|
+
rb_str_cat(str, "1", 1);
|
193
|
+
else
|
194
|
+
rb_str_cat(str, "0", 1);
|
195
|
+
}
|
196
|
+
rb_str_cat(str, ",", 1);
|
197
|
+
}
|
198
|
+
|
199
|
+
return str;
|
200
|
+
}
|
201
|
+
/*
|
202
|
+
|
203
|
+
After creating a semacode, it is possible to reuse the semacode object
|
204
|
+
if you want to encode another URL. You should call the 'encode' method
|
205
|
+
at any time to create a replacement semecode for the current object.
|
206
|
+
|
207
|
+
It returns the semacode matrix as an array of arrays of boolean. The
|
208
|
+
first element in the array is the top row, the last is the bottom row.
|
209
|
+
|
210
|
+
Each row is also an array, containing boolean values. The length of each
|
211
|
+
row is the same as the semacode width, and the number of rows is the same
|
212
|
+
as the semacode height.
|
213
|
+
|
214
|
+
*/
|
215
|
+
static VALUE
|
216
|
+
semacode_encode(VALUE self, VALUE message)
|
217
|
+
{
|
218
|
+
semacode_t *semacode;
|
219
|
+
|
220
|
+
if (!rb_respond_to(message, rb_intern ("to_s")))
|
221
|
+
rb_raise(rb_eRuntimeError, "target must respond to 'to_s'");
|
222
|
+
|
223
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
224
|
+
|
225
|
+
/* free previous string if that exists */
|
226
|
+
if(semacode->data != NULL) {
|
227
|
+
free(semacode->data);
|
228
|
+
semacode->data == NULL;
|
229
|
+
}
|
230
|
+
|
231
|
+
/* do a new encoding */
|
232
|
+
DATA_PTR(self) = encode_string(semacode, StringValueLen(message), StringValuePtr(message));
|
233
|
+
|
234
|
+
return semacode_grid(semacode);
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
This function gives the encoding organized by rows and columns.
|
239
|
+
|
240
|
+
It returns the semacode matrix as an array of arrays of boolean. The
|
241
|
+
first element in the array is the top row, the last is the bottom row.
|
242
|
+
|
243
|
+
Each row is also an array, containing boolean values. The length of each
|
244
|
+
row is the same as the semacode width, and the number of rows is the same
|
245
|
+
as the semacode height.
|
246
|
+
|
247
|
+
*/
|
248
|
+
static VALUE
|
249
|
+
semacode_data(VALUE self)
|
250
|
+
{
|
251
|
+
semacode_t *semacode;
|
252
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
253
|
+
|
254
|
+
if(semacode->data == NULL)
|
255
|
+
return Qnil;
|
256
|
+
else
|
257
|
+
return semacode_grid(semacode);
|
258
|
+
}
|
259
|
+
|
260
|
+
/*
|
261
|
+
This returns the width of the semacode.
|
262
|
+
*/
|
263
|
+
static VALUE
|
264
|
+
semacode_width(VALUE self)
|
265
|
+
{
|
266
|
+
semacode_t *semacode;
|
267
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
268
|
+
|
269
|
+
return INT2FIX(semacode->width);
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
This returns the height of the semacode.
|
274
|
+
*/
|
275
|
+
static VALUE
|
276
|
+
semacode_height(VALUE self)
|
277
|
+
{
|
278
|
+
semacode_t *semacode;
|
279
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
280
|
+
|
281
|
+
return INT2FIX(semacode->height);
|
282
|
+
}
|
283
|
+
|
284
|
+
/*
|
285
|
+
This returns the length of the semacode. It is
|
286
|
+
the same as the product of the height and the width.
|
287
|
+
*/
|
288
|
+
static VALUE
|
289
|
+
semacode_length(VALUE self)
|
290
|
+
{
|
291
|
+
semacode_t *semacode;
|
292
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
293
|
+
|
294
|
+
return INT2FIX(semacode->height * semacode->width);
|
295
|
+
}
|
296
|
+
|
297
|
+
/*
|
298
|
+
This returns the length of the raw underlying encoding
|
299
|
+
representing the data, before padding, error correction
|
300
|
+
or any other operations on the raw encoding.
|
301
|
+
*/
|
302
|
+
static VALUE
|
303
|
+
semacode_raw_encoded_length(VALUE self)
|
304
|
+
{
|
305
|
+
semacode_t *semacode;
|
306
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
307
|
+
|
308
|
+
return INT2FIX(semacode->raw_encoded_length);
|
309
|
+
}
|
310
|
+
|
311
|
+
/*
|
312
|
+
This returns the maximum number of characters that can
|
313
|
+
be stored in a symbol of the given width and height. You
|
314
|
+
can use this to decide if it is worth packing in extra
|
315
|
+
information while keeping the symbol size the same.
|
316
|
+
*/
|
317
|
+
static VALUE
|
318
|
+
semacode_symbol_size(VALUE self)
|
319
|
+
{
|
320
|
+
semacode_t *semacode;
|
321
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
322
|
+
|
323
|
+
return INT2FIX(semacode->symbol_capacity);
|
324
|
+
}
|
325
|
+
|
326
|
+
/*
|
327
|
+
This returns the number of bytes that are being devoted to
|
328
|
+
error correction.
|
329
|
+
*/
|
330
|
+
static VALUE
|
331
|
+
semacode_ecc_bytes(VALUE self)
|
332
|
+
{
|
333
|
+
semacode_t *semacode;
|
334
|
+
Data_Get_Struct(self, semacode_t, semacode);
|
335
|
+
|
336
|
+
return INT2FIX(semacode->ecc_bytes);
|
337
|
+
}
|
338
|
+
|
339
|
+
void
|
340
|
+
Init_semacode()
|
341
|
+
{
|
342
|
+
rb_mSemacode = rb_define_module ("DataMatrix");
|
343
|
+
rb_cEncoder = rb_define_class_under(rb_mSemacode, "Encoder", rb_cObject);
|
344
|
+
rb_define_alloc_func(rb_cEncoder, semacode_allocate);
|
345
|
+
|
346
|
+
rb_define_method(rb_cEncoder, "initialize", semacode_init, 1);
|
347
|
+
rb_define_method(rb_cEncoder, "encode", semacode_encode, 1);
|
348
|
+
rb_define_method(rb_cEncoder, "to_a", semacode_data, 0);
|
349
|
+
rb_define_method(rb_cEncoder, "data", semacode_data, 0);
|
350
|
+
rb_define_method(rb_cEncoder, "to_s", semacode_to_s, 0);
|
351
|
+
rb_define_method(rb_cEncoder, "to_str", semacode_to_s, 0);
|
352
|
+
rb_define_method(rb_cEncoder, "width", semacode_width, 0);
|
353
|
+
rb_define_method(rb_cEncoder, "height", semacode_height, 0);
|
354
|
+
rb_define_method(rb_cEncoder, "length", semacode_length, 0);
|
355
|
+
rb_define_method(rb_cEncoder, "size", semacode_length, 0);
|
356
|
+
rb_define_method(rb_cEncoder, "raw_encoded_length", semacode_raw_encoded_length, 0);
|
357
|
+
rb_define_method(rb_cEncoder, "symbol_size", semacode_symbol_size, 0);
|
358
|
+
rb_define_method(rb_cEncoder, "ecc_bytes", semacode_ecc_bytes, 0);
|
359
|
+
}
|