/* rll17.c -- encoder/decoder for rll17 (as defined by Jacoby and Kost) * (C) 2001, C. Bond. All rights reserved. * * Code Tables * * Primary code table (read sequence from left to right) * * source bits code bits * 00 101 * 01 100 * 10 001 * 11 010 * * Auxiliary table (to avoid invalid concatenation) * * source bits code bits * 00.00 101.000 * 00.01 100.000 * 10.00 001.000 * 10.01 010.000 * * To interpret the above encoding rules, examine the Primary code table * to determine the three output code bits corresponding to the various * combinations of two source bits. Since the requirements of an RLL 1,7 * code prohibit adjacent ones, some means must be imposed to prevent * code groups beginning with '1' from immediately following code groups * ending with '1'. For example, if a pair of zeros '00' appears in the * source stream and a '101' sequence is output, another pair of source * zeros '00', must encode from the Auxiliary table '000'. Note that the * source combination '00 01 10' outputs '100 000 001' which contains the * longest possible run of zeros. */ int rll17_encoder(unsigned char *raw, unsigned char *code, int n) /* 'raw' is a vector of ones and zeros with 1 bit per unsigned char (byte). * * 'n' is the number of bits in the source array, but note that this * is a 2/3 rate code so the destination (code) array must be 50% longer * than the source. * * The input array must be padded at the end by 4 bits to assure that all * desired bits are properly encoded. * * NOTE: it is assumed by the following that each vector element is either * a one or a zero. No checking is done to test whether other numbers are * present. */ { int i,icount,ocount,flag; unsigned char temp,otemp,lookahead; /* check for invalid input parameter */ if (n < 6) return 1; icount=ocount = 0; temp = raw[1]+(raw[0] << 1); lookahead = raw[3]+(raw[2] << 1); while (icount < n-4) { flag = 0; switch (temp) { case 0: { if (lookahead > 1) otemp = 5; else { flag = 1; if (lookahead == 0) otemp = 5; else otemp = 1; } break; } case 1: { otemp = 1; break; } case 2: { if (lookahead > 1) otemp = 4; else { flag = 1; if (lookahead == 0) otemp = 4; else otemp = 2; } break; } case 3: { otemp = 2; break; } } icount += 2; if (flag != 0) icount += 2; temp = raw[icount+1]+(raw[icount] << 1); lookahead = raw[icount+3]+(raw[icount+2] << 1); for (i = 0; i < 3*(1+flag);i++) code[ocount++] = (otemp >> i) & 1; } return 0; } int rll17_decoder(unsigned char *code,unsigned char *data, int n) { int i,icount,ocount,flag; unsigned char temp,otemp1,otemp2,lookahead; if (n < 6) return 1; icount = ocount = 0; temp = (code[0] << 2) + (code[1] << 1) + code[2]; lookahead = (code[3] << 2) + (code[4] << 1) + code[5]; while (icount < n-6) { flag = 0; switch (temp) { case 1: { if (lookahead == 0) { flag = 1; otemp1 = 1; otemp2 = 0; } else otemp1 = 1; break; } case 2: { if (lookahead == 0) { flag = 1; otemp1 = 1; otemp2 = 2; } else otemp1 = 3; break; } case 4: { if (lookahead == 0) { flag = 1; otemp1 = 0; otemp2 = 2; } else otemp1 = 2; break; } case 5: { otemp1 = 0; break; } } icount += 3; if (flag != 0) icount += 3; temp = (code[icount] << 2) + (code[icount+1] << 1) + code[icount+2]; lookahead = (code[icount+3] << 2) + (code[icount+4] << 1) + code[icount+5]; for (i = 0; i < 2; i++) data[ocount++] = (otemp1 >> i) & 1; if (flag != 0) { for (i = 0;i < 2; i++) data[ocount++] = (otemp2 >> i) & 1; } } return 0; }