Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.6 KiB

  1. /* Since the Norpak bundle FEC uses the same FEC for vertical and
  2. horizontal lines, we need to do several of the same operations
  3. on vertical and horizontal lines. However, it's difficult
  4. to share the code, because operations which work on horizontal
  5. lines want to assume that the bytes in the line are consecutive,
  6. and operations which work on vertical lines want to assume that
  7. the bytes in the line are separated by sizeof(Packet).
  8. We could just pass in a "stride" (1 for horizontal, sizeof(Packet)
  9. for vertical); but this would involve a multiplication in both
  10. the horizontal and vertical inner loops. Instead, we write the
  11. code once, and rely on various preprocessor shenanigans to
  12. create two different versions; in the horizontal version, any
  13. decent compiler will optimize away the multiplications by 1.
  14. (Basically, we just #include this file into nabtslib.c twice
  15. with different preprocessor #define's in effect; once for the
  16. horizontal and once for the vertical operations.) */
  17. /* STRIDE is #define'd in nabtslib.c to be either 1 or sizeof(Packet) */
  18. #define VALS(x) (vals[STRIDE*(x)])
  19. /* This code generates compute_csum_vert and compute_csum_horiz.
  20. Given a (horizontal or vertical) line (actually all but the
  21. last two bytes of the line), it computes the correct checksum
  22. for the line (the correct last two bytes). */
  23. int STRIDENAM(compute_csum)(unsigned char *vals, int len) {
  24. int check = 0;
  25. int i;
  26. for (i = 0; i < len; i++) {
  27. /* If VALS(i) is zero, then the byte has no effect on the checksum. */
  28. if (VALS(i)) {
  29. int bcheck = galois_log[VALS(i)];
  30. int offs0 = log_norpak_coeffs[0][i];
  31. int offs1 = log_norpak_coeffs[1][i];
  32. check ^= galois_exp[bcheck+offs0]<<8 | galois_exp[bcheck+offs1];
  33. }
  34. }
  35. return check;
  36. }
  37. /* This code generates check_checksum_vert and check_checksum_horiz.
  38. Given a (horizontal or vertical) line, it computes the error for
  39. the line (the XOR of the given checksum and the computed checksum).
  40. It then calls update_fec_inf() to determine whether the line is OK
  41. (no error), whether the error can be explained as a single-byte error,
  42. or whether the error must be at least two-byte. */
  43. fec_stat STRIDENAM(check_checksum)(unsigned char *vals, int len, fec_info *inf) {
  44. int check = STRIDENAM(compute_csum)(vals, len);
  45. inf->err = check ^ (VALS(len)<<8 | VALS(len+1));
  46. inf->errl[0] = galois_log[inf->err>>8];
  47. inf->errl[1] = galois_log[inf->err&0xff];
  48. /* The following line makes inf->status no longer be fec_status_missing
  49. (update_fec_inf does nothing for missing lines) */
  50. inf->status = fec_status_ok;
  51. return update_fec_inf(inf, len);
  52. }