diff -ru ..\zfec\zfec-1.1/zfec/_fecmodule.c ./zfec/_fecmodule.c
old
|
new
|
|
113 | 113 | PyObject* desired_blocks_nums = NULL; /* The blocknums of the blocks that should be returned. */ |
114 | 114 | PyObject* result = NULL; |
115 | 115 | |
116 | | if (!PyArg_ParseTuple(args, "O|O", &inblocks, &desired_blocks_nums)) |
117 | | return NULL; |
118 | | |
119 | | gf* check_blocks_produced[self->mm - self->kk]; /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ |
120 | | PyObject* pystrs_produced[self->mm - self->kk]; /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ |
| 116 | gf** check_blocks_produced = (gf**)alloca(self->mm - self->kk); /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ |
| 117 | PyObject** pystrs_produced = (PyObject**)alloca(self->mm - self->kk); /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ |
121 | 118 | unsigned num_check_blocks_produced = 0; /* The first num_check_blocks_produced elements of the check_blocks_produced array and of the pystrs_produced array will be used. */ |
122 | | const gf* incblocks[self->kk]; |
| 119 | const gf** incblocks = (const gf**)alloca(self->kk); |
123 | 120 | unsigned num_desired_blocks; |
124 | 121 | PyObject* fast_desired_blocks_nums = NULL; |
125 | 122 | PyObject** fast_desired_blocks_nums_items; |
126 | | unsigned c_desired_blocks_nums[self->mm]; |
127 | | unsigned c_desired_checkblocks_ids[self->mm - self->kk]; |
| 123 | unsigned* c_desired_blocks_nums = (unsigned*)alloca(self->mm); |
| 124 | unsigned* c_desired_checkblocks_ids = (unsigned*)alloca(self->mm - self->kk); |
128 | 125 | unsigned i; |
129 | 126 | PyObject* fastinblocks = NULL; |
| 127 | PyObject** fastinblocksitems; |
| 128 | Py_ssize_t sz, oldsz = 0; |
| 129 | unsigned char check_block_index = 0; /* index into the check_blocks_produced and (parallel) pystrs_produced arrays */ |
| 130 | |
| 131 | if (!PyArg_ParseTuple(args, "O|O", &inblocks, &desired_blocks_nums)) |
| 132 | return NULL; |
130 | 133 | |
131 | 134 | for (i=0; i<self->mm - self->kk; i++) |
132 | 135 | pystrs_produced[i] = NULL; |
… |
… |
|
162 | 165 | } |
163 | 166 | |
164 | 167 | /* Construct a C array of gf*'s of the input data. */ |
165 | | PyObject** fastinblocksitems = PySequence_Fast_ITEMS(fastinblocks); |
| 168 | fastinblocksitems = PySequence_Fast_ITEMS(fastinblocks); |
166 | 169 | if (!fastinblocksitems) |
167 | 170 | goto err; |
168 | | Py_ssize_t sz, oldsz = 0; |
| 171 | |
169 | 172 | for (i=0; i<self->kk; i++) { |
170 | 173 | if (!PyObject_CheckReadBuffer(fastinblocksitems[i])) { |
171 | 174 | py_raise_fec_error("Precondition violation: %u'th item is required to offer the single-segment read character buffer protocol, but it does not.", i); |
… |
… |
|
181 | 184 | } |
182 | 185 | |
183 | 186 | /* Allocate space for all of the check blocks. */ |
184 | | unsigned char check_block_index = 0; /* index into the check_blocks_produced and (parallel) pystrs_produced arrays */ |
| 187 | |
185 | 188 | for (i=0; i<num_desired_blocks; i++) { |
186 | 189 | if (c_desired_blocks_nums[i] >= self->kk) { |
187 | 190 | c_desired_checkblocks_ids[check_block_index] = c_desired_blocks_nums[i]; |
… |
… |
|
371 | 374 | PyObject*restrict blocknums; |
372 | 375 | PyObject* result = NULL; |
373 | 376 | |
| 377 | const gf**restrict cblocks = (const gf**restrict)alloca(self->kk); |
| 378 | unsigned* cblocknums = (unsigned*)alloca(self->kk); |
| 379 | gf**restrict recoveredcstrs = (gf**)alloca(self->kk); /* self->kk is actually an upper bound -- we probably won't need all of this space. */ |
| 380 | PyObject**restrict recoveredpystrs = (PyObject**restrict)alloca(self->kk); /* self->kk is actually an upper bound -- we probably won't need all of this space. */ |
| 381 | unsigned i; |
| 382 | PyObject*restrict fastblocknums = NULL; |
| 383 | PyObject*restrict fastblocks; |
| 384 | unsigned needtorecover=0; |
| 385 | PyObject** fastblocksitems; |
| 386 | PyObject** fastblocknumsitems; |
| 387 | Py_ssize_t sz, oldsz = 0; |
| 388 | long tmpl; |
| 389 | unsigned nextrecoveredix=0; |
| 390 | |
374 | 391 | if (!PyArg_ParseTuple(args, "OO", &blocks, &blocknums)) |
375 | 392 | return NULL; |
376 | 393 | |
377 | | const gf*restrict cblocks[self->kk]; |
378 | | unsigned cblocknums[self->kk]; |
379 | | gf*restrict recoveredcstrs[self->kk]; /* self->kk is actually an upper bound -- we probably won't need all of this space. */ |
380 | | PyObject*restrict recoveredpystrs[self->kk]; /* self->kk is actually an upper bound -- we probably won't need all of this space. */ |
381 | | unsigned i; |
382 | 394 | for (i=0; i<self->kk; i++) |
383 | 395 | recoveredpystrs[i] = NULL; |
384 | | PyObject*restrict fastblocknums = NULL; |
385 | | PyObject*restrict fastblocks = PySequence_Fast(blocks, "First argument was not a sequence."); |
| 396 | fastblocks = PySequence_Fast(blocks, "First argument was not a sequence."); |
386 | 397 | if (!fastblocks) |
387 | 398 | goto err; |
388 | 399 | fastblocknums = PySequence_Fast(blocknums, "Second argument was not a sequence."); |
… |
… |
|
399 | 410 | } |
400 | 411 | |
401 | 412 | /* Construct a C array of gf*'s of the data and another of C ints of the blocknums. */ |
402 | | unsigned needtorecover=0; |
403 | | PyObject** fastblocknumsitems = PySequence_Fast_ITEMS(fastblocknums); |
| 413 | fastblocknumsitems = PySequence_Fast_ITEMS(fastblocknums); |
404 | 414 | if (!fastblocknumsitems) |
405 | 415 | goto err; |
406 | | PyObject** fastblocksitems = PySequence_Fast_ITEMS(fastblocks); |
| 416 | fastblocksitems = PySequence_Fast_ITEMS(fastblocks); |
407 | 417 | if (!fastblocksitems) |
408 | 418 | goto err; |
409 | | Py_ssize_t sz, oldsz = 0; |
| 419 | |
410 | 420 | for (i=0; i<self->kk; i++) { |
411 | 421 | if (!PyInt_Check(fastblocknumsitems[i])) { |
412 | 422 | py_raise_fec_error("Precondition violation: second argument is required to contain int."); |
413 | 423 | goto err; |
414 | 424 | } |
415 | | long tmpl = PyInt_AsLong(fastblocknumsitems[i]); |
| 425 | tmpl = PyInt_AsLong(fastblocknumsitems[i]); |
416 | 426 | if (tmpl < 0 || tmpl > 255) { |
417 | 427 | py_raise_fec_error("Precondition violation: block nums can't be less than zero or greater than 255. %ld\n", tmpl); |
418 | 428 | goto err; |
… |
… |
|
462 | 472 | fec_decode(self->fec_matrix, cblocks, recoveredcstrs, cblocknums, sz); |
463 | 473 | |
464 | 474 | /* Wrap up both original primary blocks and decoded blocks into a Python list of Python strings. */ |
465 | | unsigned nextrecoveredix=0; |
466 | 475 | result = PyList_New(self->kk); |
467 | 476 | if (result == NULL) |
468 | 477 | goto err; |
diff -ru ..\zfec\zfec-1.1/zfec/fec.c ./zfec/fec.c
old
|
new
|
|
494 | 494 | |
495 | 495 | void |
496 | 496 | fec_decode(const fec_t* code, const gf*restrict const*restrict const inpkts, gf*restrict const*restrict const outpkts, const unsigned*restrict const index, size_t sz) { |
497 | | gf m_dec[code->k * code->k]; |
| 497 | gf* m_dec = (gf*)alloca(code->k * code->k); |
| 498 | unsigned char outix=0; |
| 499 | unsigned char row=0; |
| 500 | unsigned char col=0; |
498 | 501 | build_decode_matrix_into_space(code, index, code->k, m_dec); |
499 | 502 | |
500 | | unsigned char outix=0; |
501 | | for (unsigned char row=0; row<code->k; row++) { |
| 503 | for (row=0; row<code->k; row++) { |
502 | 504 | if (index[row] >= code->k) { |
503 | 505 | memset(outpkts[outix], 0, sz); |
504 | | for (unsigned char col=0; col < code->k; col++) |
| 506 | for (col=0; col < code->k; col++) |
505 | 507 | addmul(outpkts[outix], inpkts[col], m_dec[row * code->k + col], sz); |
506 | 508 | outix++; |
507 | 509 | } |
diff -ru ..\zfec\zfec-1.1/zfec/fec.h ./zfec/fec.h
old
|
new
|
|
2 | 2 | * zfec -- fast forward error correction library with Python interface |
3 | 3 | */ |
4 | 4 | |
| 5 | #if defined(_MSC_VER) |
| 6 | // actually, some of the flavors (i.e. Enterprise) do support it |
| 7 | //#define restrict __restrict |
| 8 | #define restrict |
| 9 | #define inline __inline |
| 10 | #define alloca _alloca |
| 11 | #endif |
| 12 | |
5 | 13 | typedef unsigned char gf; |
6 | 14 | |
7 | 15 | typedef struct { |