PageRenderTime 25ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/cpu-rs.c

https://gitlab.com/inesdauscha/gpu-rscode
C | 855 lines | 649 code | 89 blank | 117 comment | 97 complexity | 1bed024e51b4706149299224a7a07be2 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: CPU-RS.c
  5. *
  6. * Description:
  7. *
  8. * Version: 1.0
  9. * Created: 12/05/2012 10:42:32 PM
  10. * Revision: none
  11. * Compiler: gcc
  12. *
  13. * Author: Shuai YUAN(yszheda AT gmail.com),
  14. * Company:
  15. *
  16. * =====================================================================================
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <math.h>
  23. #include <time.h>
  24. //#include "galoisfield.h"
  25. #define IDC2D(i,j,ld) (((i)*(ld))+(j))
  26. //extern uint8_t encodingMatrix[];
  27. //extern unsigned char encodingMatrix[];
  28. //unsigned char* encodingMatrix;
  29. const int w = 8;
  30. const int NW = 1 << 8;
  31. //#define NW (1 << w) /* In other words, NW equals 2 to the w-th power */
  32. //#define DEBUG
  33. #define BUFFER_SIZE 256
  34. //unsigned int prim_poly_4 = 023;
  35. //unsigned int prim_poly_8 = 0435;
  36. //unsigned int prim_poly_16 = 0210013;
  37. unsigned int prim_poly_4 = 023;
  38. unsigned int prim_poly_8 = 0435;
  39. //uint8_t prim_poly_8 = 285;
  40. unsigned int prim_poly_16 = 0210013;
  41. //uint8_t *gflog;
  42. //uint8_t *gfilog;
  43. uint8_t gflog[256];
  44. uint8_t gfilog[256];
  45. int setup_tables(int w)
  46. {
  47. unsigned int b;
  48. unsigned int r;
  49. unsigned int log;
  50. unsigned int x_to_w;
  51. unsigned int prim_poly;
  52. unsigned int x;
  53. unsigned int y;
  54. // uint8_t b, log, x_to_w, prim_poly;
  55. switch(w)
  56. {
  57. case 4: prim_poly = prim_poly_4; break;
  58. case 8: prim_poly = prim_poly_8; break;
  59. case 16: prim_poly = prim_poly_16; break;
  60. default: return -1;
  61. }
  62. x_to_w = 1 << w;
  63. // gflog = (uint8_t *) malloc (sizeof(uint8_t) * x_to_w);
  64. // gfilog = (uint8_t *) malloc (sizeof(uint8_t) * x_to_w);
  65. b = 1;
  66. r = 0;
  67. for (log = 0; log < x_to_w-1; log++)
  68. {
  69. /*
  70. r = 0;
  71. x = 1;
  72. y = log;
  73. while(y)
  74. {
  75. printf("y=%d\n",y);
  76. if(y & 1)
  77. {
  78. r = r ^ b;
  79. }
  80. y = y >> 1;
  81. x = x << 1;
  82. if (x & x_to_w) x = x ^ prim_poly;
  83. }
  84. printf("r=%d\n",r);
  85. printf("log=%d\n",log);
  86. */
  87. if(b>x_to_w) break;
  88. gflog[b] = (uint8_t) log;
  89. gfilog[log] = (uint8_t) b;
  90. b = b << 1;
  91. if (b & x_to_w)
  92. {
  93. b = b ^ prim_poly;
  94. //#ifdef DEBUG
  95. //printf("prim_poly=%d\n", prim_poly);
  96. //printf("test b=%d\n", b);
  97. //#endif
  98. }
  99. }
  100. //#ifdef DEBUG
  101. // printf("b=%d\n",b);
  102. //#endif
  103. return 0;
  104. }
  105. void showgflog()
  106. {
  107. int i;
  108. printf("gflog\n");
  109. for(i =0; i< NW; i++)
  110. {
  111. printf("%d ", gflog[i]);
  112. }
  113. }
  114. void showgfilog()
  115. {
  116. int i;
  117. printf("gfilog\n");
  118. for(i =0; i< NW; i++)
  119. {
  120. printf("%d ", gfilog[i]);
  121. }
  122. }
  123. uint8_t gf_add(uint8_t a, uint8_t b)
  124. {
  125. return a^b;
  126. }
  127. uint8_t gf_sub(uint8_t a, uint8_t b)
  128. {
  129. return gf_add(a, b);
  130. }
  131. uint8_t gf_mul(uint8_t a, uint8_t b)
  132. {
  133. int sum_log;
  134. if (a == 0 || b == 0)
  135. {
  136. return 0;
  137. }
  138. // sum_log = (gflog[a] + gflog[b]) % (NW-1);
  139. sum_log = gflog[a] + gflog[b];
  140. if (sum_log >= NW-1)
  141. {
  142. sum_log -= NW-1;
  143. }
  144. return gfilog[sum_log];
  145. }
  146. uint8_t gf_mul_bit(uint8_t a, uint8_t b)
  147. {
  148. int sum_log;
  149. while(b)
  150. {
  151. if(b & 1)
  152. {
  153. sum_log ^= a;
  154. }
  155. a = (a << 1) ^ (a & 0x80? 0x1d: 0);
  156. b >>= 1;
  157. }
  158. return sum_log;
  159. }
  160. uint8_t gf_div(uint8_t a, uint8_t b)
  161. {
  162. int diff_log;
  163. if (a == 0)
  164. {
  165. return 0;
  166. }
  167. /* Can’t divide by 0 */
  168. if (b == 0)
  169. {
  170. return -1;
  171. }
  172. // diff_log = (gflog[a] - gflog[b]) % (NW-1);
  173. diff_log = gflog[a] - gflog[b];
  174. if (diff_log < 0)
  175. {
  176. diff_log += NW-1;
  177. }
  178. return gfilog[diff_log];
  179. }
  180. uint8_t gf_pow(uint8_t a, uint8_t power)
  181. {
  182. int pow_log = (gflog[a] * power) % (NW-1);
  183. return gfilog[pow_log];
  184. }
  185. void show_squre_matrix(uint8_t *matrix, int size)
  186. {
  187. int i;
  188. int j;
  189. for(i=0; i<size; i++)
  190. {
  191. for(j=0; j<size; j++)
  192. {
  193. printf("%d ", matrix[i*size+j]);
  194. }
  195. printf("\n");
  196. }
  197. }
  198. void gen_encoding_matrix(uint8_t *encodingMatrix, int row, int col)
  199. {
  200. int i;
  201. int j;
  202. for(i = 0; i < row; i++)
  203. {
  204. for(j = 0; j < col; j++)
  205. {
  206. encodingMatrix[i*col + j] = gf_pow(j+1, i);
  207. }
  208. }
  209. }
  210. // C=AB
  211. // A: nxp
  212. // B: pxm
  213. // C: nxm
  214. void matrix_mul(uint8_t *A, uint8_t *B, uint8_t *C, int n, int p, int m)
  215. {
  216. int i;
  217. int j;
  218. int k;
  219. for(i=0; i<n; i++)
  220. {
  221. for(j=0; j<m; j++)
  222. {
  223. for(k=0; k<p; k++)
  224. {
  225. // C[i*m+j] = gf_add(C[i*m+j], gf_mul(A[i*p+k],B[k*m+j]));
  226. C[i*m+j] ^= gf_mul(A[i*p+k],B[k*m+j]);
  227. }
  228. }
  229. }
  230. }
  231. // switch rows if the current row is not the pivot row
  232. void switch_rows(uint8_t *matrix, uint8_t *result, int rowSrc, int rowDes, int size)
  233. {
  234. int col;
  235. uint8_t oldMatrixItem;
  236. uint8_t oldResultItem;
  237. for(col=0; col<size; col++)
  238. {
  239. oldMatrixItem = matrix[ rowSrc*size+col ];
  240. matrix[ rowSrc*size+col ] = matrix[ rowDes*size+col ];
  241. matrix[ IDC2D(rowDes, col, size) ] = oldMatrixItem;
  242. oldResultItem = result[ IDC2D(rowSrc, col, size) ];
  243. result[ IDC2D(rowSrc, col, size) ] = result[ IDC2D(rowDes, col, size) ];
  244. result[ IDC2D(rowDes, col, size) ] = oldResultItem;
  245. }
  246. }
  247. void switch_columns(uint8_t *matrix, uint8_t *result, int colSrc, int colDes, int size)
  248. {
  249. int row;
  250. uint8_t oldMatrixItem;
  251. uint8_t oldResultItem;
  252. for(row=0; row<size; row++)
  253. {
  254. oldMatrixItem = matrix[ IDC2D(row, colSrc, size) ];
  255. matrix[ IDC2D(row, colSrc, size) ] = matrix[ IDC2D(row, colDes, size) ];
  256. matrix[ IDC2D(row, colDes, size) ] = oldMatrixItem;
  257. oldResultItem = result[ IDC2D(row, colSrc, size) ];
  258. result[ IDC2D(row, colSrc, size) ] = result[ IDC2D(row, colDes, size) ];
  259. result[ IDC2D(row, colSrc, size) ] = oldResultItem;
  260. }
  261. }
  262. // normalize the row by the pivot value
  263. void normalize_pivot_row(uint8_t *matrix, uint8_t *result, int row, int size)
  264. {
  265. int col;
  266. uint8_t pivotValue;
  267. pivotValue = matrix[ IDC2D(row, row, size) ];
  268. for(col=0; col<size; col++)
  269. {
  270. matrix[ IDC2D(row, col, size)] = gf_div(matrix[ IDC2D(row, col, size) ], pivotValue);
  271. result[ IDC2D(row, col, size)] = gf_div(result[ IDC2D(row, col, size) ], pivotValue);
  272. }
  273. }
  274. // normalize the column by the pivot value
  275. void normalize_pivot_col(uint8_t *matrix, uint8_t *result, int col, int size)
  276. {
  277. int row;
  278. uint8_t pivotValue;
  279. pivotValue = matrix[ IDC2D(col, col, size) ];
  280. for(row=0; row<size; row++)
  281. {
  282. matrix[ IDC2D(row, col, size)] = gf_div(matrix[ IDC2D(row, col, size) ], pivotValue);
  283. result[ IDC2D(row, col, size)] = gf_div(result[ IDC2D(row, col, size) ], pivotValue);
  284. }
  285. }
  286. //eliminate by row to make the pivot column become reduced echelon form
  287. void eliminate_by_row(uint8_t *matrix, uint8_t *result, int pivotIndex, int size)
  288. {
  289. int row;
  290. int col;
  291. uint8_t matrixPivotValue;
  292. uint8_t resultPivotValue;
  293. uint8_t pivotColItem;
  294. for(row=0; row<size; row++)
  295. {
  296. pivotColItem = matrix[ IDC2D(row, pivotIndex, size) ];
  297. for(col=0; col<size; col++)
  298. {
  299. matrixPivotValue = matrix[ IDC2D(pivotIndex, col, size) ];
  300. resultPivotValue = result[ IDC2D(pivotIndex, col, size) ];
  301. if(row != pivotIndex)
  302. {
  303. matrix[ IDC2D(row, col, size) ] ^= gf_mul(pivotColItem, matrixPivotValue);
  304. result[ IDC2D(row, col, size) ] ^= gf_mul(pivotColItem, resultPivotValue);
  305. }
  306. }
  307. }
  308. }
  309. //eliminate by column to make the pivot row become reduced echelon form
  310. void eliminate_by_col(uint8_t *matrix, uint8_t *result, int pivotIndex, int size)
  311. {
  312. int row;
  313. int col;
  314. uint8_t matrixPivotValue;
  315. uint8_t resultPivotValue;
  316. uint8_t pivotRowItem;
  317. for(row=0; row<size; row++)
  318. {
  319. matrixPivotValue = matrix[ IDC2D(row, pivotIndex, size) ];
  320. resultPivotValue = result[ IDC2D(row, pivotIndex, size) ];
  321. for(col=0; col<size; col++)
  322. {
  323. pivotRowItem = matrix[ IDC2D(pivotIndex, col, size) ];
  324. if(col != pivotIndex)
  325. {
  326. matrix[ IDC2D(row, col, size) ] ^= gf_mul(pivotRowItem, matrixPivotValue);
  327. result[ IDC2D(row, col, size) ] ^= gf_mul(pivotRowItem, resultPivotValue);
  328. }
  329. }
  330. }
  331. }
  332. //generate an identity matrix
  333. void get_identity_matrix(uint8_t *result, int size)
  334. {
  335. int i;
  336. int j;
  337. for(i=0; i<size; i++)
  338. {
  339. for(j=0; j<size; j++)
  340. {
  341. if(i == j)
  342. {
  343. result[i*size+j] = 1;
  344. }
  345. else
  346. {
  347. result[i*size+j] = 0;
  348. }
  349. }
  350. }
  351. }
  352. //find the pivot index in the given row/column
  353. int get_pivot_index(uint8_t *vector, int index, int size)
  354. {
  355. int pivotIndex = -1;
  356. int i = index;
  357. while( pivotIndex == -1 && i < size )
  358. {
  359. pivotIndex = (vector[i] > 0)? i: -1;
  360. i++;
  361. }
  362. return pivotIndex;
  363. }
  364. // compute the inverse of a given matrix
  365. // Guassian elimination
  366. void invert_matrix(uint8_t *matrix, uint8_t *result, int size)
  367. {
  368. int row;
  369. int pivotIndex;
  370. uint8_t currentRow[size];
  371. int currentRowSize = size*sizeof(uint8_t);
  372. get_identity_matrix(result, size);
  373. #ifdef DEBUG
  374. printf("original matrix:\n");
  375. show_squre_matrix(matrix, size);
  376. printf("result: \n");
  377. show_squre_matrix(result,size);
  378. #endif
  379. for(row=0; row<size; row++)
  380. {
  381. // check whether the leading coefficient of the current row is in the 'index'th column
  382. int index = row;
  383. memcpy(&currentRow, matrix+row*size, currentRowSize);
  384. pivotIndex = get_pivot_index(currentRow, index, size);
  385. if( pivotIndex != row )
  386. {
  387. switch_columns(matrix, result, index, pivotIndex, size);
  388. }
  389. // Normalize the pivot row
  390. normalize_pivot_row(matrix, result, index, size);
  391. #ifdef DEBUG
  392. printf("original matrix:\n");
  393. show_squre_matrix(matrix, size);
  394. printf("result: \n");
  395. show_squre_matrix(result,size);
  396. #endif
  397. eliminate_by_row(matrix, result, row, size);
  398. #ifdef DEBUG
  399. printf("original matrix:\n");
  400. show_squre_matrix(matrix, size);
  401. printf("result: \n");
  402. show_squre_matrix(result,size);
  403. #endif
  404. }
  405. }
  406. void encode_chunk(uint8_t *dataChunk, uint8_t *parityCoeff, uint8_t *codeChunk, int nativeBlockNum, int parityBlockNum, int chunkSize)
  407. {
  408. // codeChunk = (unsigned char*)malloc(parityBlockNum*chunkSize);
  409. // codeChunk = (uint8_t*) malloc( parityBlockNum*chunkSize*sizeof(uint8_t) );
  410. matrix_mul(parityCoeff, dataChunk, codeChunk, parityBlockNum, nativeBlockNum, chunkSize);
  411. }
  412. void decode_chunk(unsigned char *dataChunk, unsigned char *parityCoeff, unsigned char *codeChunk, int nativeBlockNum, int parityBlockNum, int chunkSize)
  413. {
  414. matrix_mul(parityCoeff, codeChunk, dataChunk, nativeBlockNum, nativeBlockNum, chunkSize);
  415. }
  416. void show_code_chunk(unsigned char *codeChunk, int parityBlockNum, int chunkSize)
  417. {
  418. int i;
  419. int j;
  420. for(i=0; i<parityBlockNum; i++)
  421. {
  422. for(j=0; j<chunkSize; j++)
  423. {
  424. printf("%d ", codeChunk[i*chunkSize+j]);
  425. }
  426. printf("\n");
  427. }
  428. }
  429. void show_matrix(uint8_t *matrix, int row, int col)
  430. {
  431. int i;
  432. int j;
  433. for(i=0; i<row; i++)
  434. {
  435. for(j=0; j<col; j++)
  436. {
  437. printf("%d ", matrix[i*col+j]);
  438. }
  439. printf("\n");
  440. }
  441. }
  442. void copy_matrix(uint8_t *src, uint8_t *des, int srcRowIndex, int desRowIndex, int rowSize)
  443. {
  444. int i;
  445. for(i=0; i<rowSize; i++)
  446. {
  447. des[desRowIndex*rowSize+i] = src[srcRowIndex*rowSize+i];
  448. }
  449. }
  450. void write_metadata(int totalSize, int parityBlockNum, int nativeBlockNum, uint8_t *encodingMatrix)
  451. {
  452. FILE *fp;
  453. if( ( fp = fopen(".METADATA", "wb") ) == NULL )
  454. {
  455. printf("Can not open META file!\n");
  456. exit(0);
  457. }
  458. fprintf(fp, "%d\n", totalSize);
  459. fprintf(fp, "%d %d\n", parityBlockNum, nativeBlockNum);
  460. int i;
  461. int j;
  462. for(i=0; i<nativeBlockNum; i++)
  463. {
  464. for(j=0; j<nativeBlockNum; j++)
  465. {
  466. if(i == j)
  467. {
  468. fprintf(fp, "1 ");
  469. }
  470. else
  471. {
  472. fprintf(fp, "0 ");
  473. }
  474. }
  475. fprintf(fp, "\n");
  476. }
  477. for(i=0; i<parityBlockNum; i++)
  478. {
  479. for(j=0; j<nativeBlockNum; j++)
  480. {
  481. fprintf(fp, "%d ", encodingMatrix[i*nativeBlockNum+j]);
  482. }
  483. fprintf(fp, "\n");
  484. }
  485. fclose(fp);
  486. }
  487. void encode_file(char *file, int nativeBlockNum, int parityBlockNum)
  488. {
  489. int chunkSize = 1;
  490. int totalSize;
  491. FILE *fp_in;
  492. FILE *fp_out;
  493. if( ( fp_in = fopen(file,"rb") ) == NULL )
  494. {
  495. printf("Can not open source file!\n");
  496. exit(0);
  497. }
  498. fseek(fp_in, 0L, SEEK_END);
  499. //ftell() get the total size of the file
  500. totalSize = ftell(fp_in);
  501. chunkSize = (totalSize / nativeBlockNum) + ( totalSize%nativeBlockNum != 0 );
  502. // chunkSize = (ftell(fp_in) / nativeBlockNum) + ( ftell(fp_in)%nativeBlockNum != 0 );
  503. // chunkSize = (int) (ceil( (long double) (ftell(fp_in) / nativeBlockNum)) );
  504. uint8_t *dataBuf; //host
  505. uint8_t *codeBuf; //host
  506. int dataSize = nativeBlockNum*chunkSize*sizeof(uint8_t);
  507. int codeSize = parityBlockNum*chunkSize*sizeof(uint8_t);
  508. dataBuf = (uint8_t*) malloc( nativeBlockNum*chunkSize*sizeof(uint8_t) );
  509. memset(dataBuf, 0, dataSize);
  510. codeBuf = (uint8_t*) malloc( parityBlockNum*chunkSize*sizeof(uint8_t) );
  511. memset(codeBuf, 0, codeSize);
  512. int i;
  513. for(i=0; i<nativeBlockNum; i++)
  514. {
  515. if( fseek( fp_in, i*chunkSize, SEEK_SET ) == -1 )
  516. {
  517. printf("fseek error!\n");
  518. exit(0);
  519. }
  520. if( fread( dataBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in ) == EOF )
  521. {
  522. printf("fread error!\n");
  523. exit(0);
  524. }
  525. }
  526. fclose(fp_in);
  527. struct timespec start, end;
  528. double totalTime;
  529. clock_gettime(CLOCK_REALTIME,&start);
  530. // // setup table for GF(2^8)
  531. // setup_tables(8);
  532. uint8_t *encodingMatrix;
  533. encodingMatrix = (uint8_t*) malloc( parityBlockNum*nativeBlockNum*sizeof(uint8_t) );
  534. gen_encoding_matrix(encodingMatrix, parityBlockNum, nativeBlockNum);
  535. write_metadata(totalSize, parityBlockNum, nativeBlockNum, encodingMatrix);
  536. encode_chunk(dataBuf, encodingMatrix, codeBuf, nativeBlockNum, parityBlockNum, chunkSize);
  537. // matrix_mul(encodingMatrix, dataBuf, codeBuf, parityBlockNum, nativeBlockNum, chunkSize);
  538. /*
  539. //int i;
  540. int j;
  541. int k;
  542. int n=parityBlockNum;
  543. int p=nativeBlockNum;
  544. int m=chunkSize;
  545. for(i=0; i<n; i++)
  546. {
  547. for(j=0; j<m; j++)
  548. {
  549. codeBuf[i*m+j] = 0;
  550. for(k=0; k<p; k++)
  551. {
  552. // C[i*m+j] = gf_add(C[i*m+j], gf_mul(A[i*p+k],B[k*m+j]));
  553. codeBuf[i*m+j] ^= gf_mul(encodingMatrix[i*p+k],dataBuf[k*m+j]);
  554. }
  555. }
  556. }
  557. */
  558. clock_gettime(CLOCK_REALTIME,&end);
  559. totalTime = (double)(end.tv_sec-start.tv_sec)*1000+(double)(end.tv_nsec-start.tv_nsec)/(double)1000000L;
  560. printf("Total CPU encoding time: %fms\n", totalTime);
  561. char output_file_name[100];
  562. for(i=0; i<nativeBlockNum; i++)
  563. {
  564. sprintf(output_file_name, "_%d_", i);
  565. strcat(output_file_name, file);
  566. if( ( fp_out = fopen(output_file_name, "wb") ) == NULL )
  567. {
  568. printf("Can not open source file!\n");
  569. exit(0);
  570. }
  571. if( fwrite(dataBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_out ) != sizeof(uint8_t)*chunkSize )
  572. {
  573. printf("fwrite error!\n");
  574. exit(0);
  575. }
  576. fclose(fp_out);
  577. }
  578. for(i=0; i<parityBlockNum; i++)
  579. {
  580. sprintf(output_file_name, "_%d_", i+nativeBlockNum);
  581. strcat(output_file_name, file);
  582. if( ( fp_out = fopen(output_file_name, "wb") ) == NULL )
  583. {
  584. printf("Can not open source file!\n");
  585. exit(0);
  586. }
  587. if( fwrite(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_out ) != sizeof(uint8_t)*chunkSize )
  588. {
  589. printf("fwrite error!\n");
  590. exit(0);
  591. }
  592. fclose(fp_out);
  593. }
  594. free(dataBuf);
  595. free(codeBuf);
  596. free(encodingMatrix);
  597. }
  598. void decode_file(char *confFile, char *outFile, int nativeBlockNum, int parityBlockNum)
  599. {
  600. int chunkSize = 1;
  601. int totalSize;
  602. uint8_t *dataBuf;
  603. uint8_t *codeBuf;
  604. int dataSize;
  605. int codeSize;
  606. FILE *fp_in;
  607. FILE *fp_out;
  608. int totalMatrixSize;
  609. int matrixSize;
  610. uint8_t *totalEncodingMatrix;
  611. uint8_t *encodingMatrix;
  612. if( ( fp_in = fopen(".METADATA","rb") ) == NULL )
  613. {
  614. printf("Can not open source file!\n");
  615. exit(0);
  616. }
  617. fscanf(fp_in, "%d", &totalSize);
  618. fscanf(fp_in, "%d %d", &parityBlockNum, &nativeBlockNum);
  619. // chunkSize = (int) (ceil( (float) (totalSize / nativeBlockNum) ));
  620. chunkSize = (totalSize / nativeBlockNum) + ( totalSize%nativeBlockNum != 0 );
  621. #ifdef DEBUG
  622. printf("chunk size: %d\n", chunkSize);
  623. #endif
  624. totalMatrixSize = nativeBlockNum * ( nativeBlockNum + parityBlockNum );
  625. totalEncodingMatrix = (uint8_t*) malloc( totalMatrixSize );
  626. matrixSize = nativeBlockNum * nativeBlockNum;
  627. encodingMatrix = (uint8_t*) malloc( matrixSize );
  628. int i;
  629. for(i =0; i<nativeBlockNum*(nativeBlockNum+parityBlockNum); i++)
  630. {
  631. fscanf(fp_in, "%d", totalEncodingMatrix+i);
  632. }
  633. dataSize = nativeBlockNum*chunkSize*sizeof(uint8_t);
  634. codeSize = nativeBlockNum*chunkSize*sizeof(uint8_t);
  635. dataBuf = (uint8_t*) malloc( dataSize );
  636. memset(dataBuf, 0, dataSize);
  637. codeBuf = (uint8_t*) malloc( codeSize);
  638. memset(codeBuf, 0, codeSize);
  639. if(confFile != NULL)
  640. {
  641. FILE *fp_conf;
  642. char input_file_name[100];
  643. int index;
  644. fp_conf = fopen(confFile, "r");
  645. for(i=0; i<nativeBlockNum; i++)
  646. {
  647. fscanf(fp_conf, "%s", input_file_name);
  648. index = atoi(input_file_name+1);
  649. copy_matrix(totalEncodingMatrix, encodingMatrix, index, i, nativeBlockNum);
  650. fp_in = fopen(input_file_name, "rb");
  651. fseek(fp_in, 0L, SEEK_SET);
  652. // this part can be process in parallel with computing inversed matrix
  653. fread(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in);
  654. fclose(fp_in);
  655. }
  656. fclose(fp_conf);
  657. }
  658. else
  659. {
  660. for(i=0; i<nativeBlockNum; i++)
  661. {
  662. char input_file_name[100];
  663. int index;
  664. printf("Please enter the file name of fragment:\n");
  665. scanf("%s", input_file_name);
  666. index = atoi(input_file_name+1);
  667. printf("#%dth fragment\n", index);
  668. copy_matrix(totalEncodingMatrix, encodingMatrix, index, i, nativeBlockNum);
  669. fp_in = fopen(input_file_name, "rb");
  670. fseek(fp_in, 0L, SEEK_SET);
  671. // TODO: this part can be process in parallel with computing inversed matrix
  672. fread(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in);
  673. fclose(fp_in);
  674. }
  675. }
  676. struct timespec start, end;
  677. double totalTime;
  678. clock_gettime(CLOCK_REALTIME,&start);
  679. uint8_t *decodingMatrix;
  680. decodingMatrix = (uint8_t*) malloc( matrixSize );
  681. invert_matrix(encodingMatrix, decodingMatrix, nativeBlockNum);
  682. //#ifndef DEBUG
  683. // show_matrix(totalEncodingMatrix, nativeBlockNum+parityBlockNum, nativeBlockNum);
  684. //#endif
  685. //#ifndef DEBUG
  686. decode_chunk(dataBuf, decodingMatrix, codeBuf, nativeBlockNum, parityBlockNum, chunkSize);
  687. //#endif
  688. //#ifdef DEBUG
  689. // uint8_t test_DM[16] = {1,0,0,0, 2,1,3,7, 3,1,2,6, 0,0,0,1};
  690. // decode_chunk(dataBuf, test_DM, codeBuf, nativeBlockNum, parityBlockNum, chunkSize);
  691. //#endif
  692. clock_gettime(CLOCK_REALTIME,&end);
  693. totalTime = (double)(end.tv_sec-start.tv_sec)*1000+(double)(end.tv_nsec-start.tv_nsec)/(double)1000000L;
  694. printf("Total CPU decoding time: %fms\n", totalTime);
  695. if(outFile == NULL)
  696. {
  697. char output_file_name[100];
  698. printf("Enter the name of the decoded file:\n");
  699. scanf("%s", output_file_name);
  700. fp_out = fopen(output_file_name, "wb");
  701. }
  702. else
  703. {
  704. fp_out = fopen(outFile, "wb");
  705. }
  706. fwrite(dataBuf, sizeof(uint8_t), totalSize, fp_out);
  707. fclose(fp_out);
  708. free(dataBuf);
  709. free(codeBuf);
  710. }
  711. int main(int argc, char *argv[])
  712. {
  713. int nativeBlockNum = 4;
  714. int parityBlockNum = 2;
  715. char *inFile = NULL;
  716. char *confFile = NULL;
  717. char *outFile = NULL;
  718. enum func
  719. {
  720. encode,
  721. decode
  722. };
  723. enum func op;
  724. nativeBlockNum = atoi(argv[1]);
  725. parityBlockNum = atoi(argv[2]);
  726. if( strcmp(argv[3], "-e") == 0 )
  727. {
  728. op = encode;
  729. }
  730. else if( strcmp(argv[3], "-d") == 0 )
  731. {
  732. op = decode;
  733. }
  734. else
  735. {
  736. printf("Invalid option!\n");
  737. exit(-1);
  738. }
  739. // setup table for GF(2^8)
  740. setup_tables(8);
  741. switch(op)
  742. {
  743. case encode:
  744. inFile = argv[4];
  745. encode_file(inFile, nativeBlockNum, parityBlockNum);
  746. break;
  747. case decode:
  748. if(argc == 5)
  749. {
  750. confFile = argv[4];
  751. }
  752. else if(argc == 7 && strcmp(argv[5], "-o") == 0)
  753. {
  754. confFile = argv[4];
  755. outFile = argv[6];
  756. }
  757. else
  758. {
  759. printf("Invalid command!\n");
  760. exit(-1);
  761. }
  762. decode_file(confFile, outFile, nativeBlockNum, parityBlockNum);
  763. break;
  764. }
  765. return 0;
  766. }