semacode 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|