static float float_medv(float *x, int n) { if (!n) fail("empty list of pixel values!"); if (n == 1) return x[0]; if (n == 2) return (x[0] + x[1])/2; qsort(x, n, sizeof*x, compare_floats); if (EVENP(n)) return (x[n/2] + x[1+n/2])/2; else return x[n/2]; }
static void statistics_getf_spoilable(struct statistics_float *s, float *f, int n) { s->middle = f[n/2-1]; int mt = STATISTIC_MEDIAN_BIAS; int mi = STATISTIC_MIDDLE_BIAS; switch(mi) { case -1: break; case 0: s->middle += f[n/2]; s->middle /=2; break; case 1: s->middle = f[n/2]; break; default: error("bad STATISTIC_MEDIAN_BIAS %d", mt); } // qsort(f, n, sizeof*f, compare_floats); s->min = f[0]; s->max = f[n-1]; s->median = f[n/2-1]; if (EVENP(n)) { int mtype = STATISTIC_MEDIAN_BIAS; switch(mtype) { case -1: break; case 0: s->median += f[n/2]; s->median /=2; break; case 1: s->median = f[n/2]; break; default: error("bad STATISTIC_MEDIAN_BIAS %d", mtype); } } s->average = 0; for (int i = 0; i < n; i++) s->average += f[i]; s->average /= n; s->laverage = 0; for (int i = 0; i < n; i++) s->laverage += exp(f[i]/255); s->laverage = log(s->laverage/n)*255; s->variance = 0; for (int i = 0; i < n; i++) s->variance = hypot(s->variance, s->average - f[i]); s->sample = f[randombounds(0, n-1)]; }
float op_median(float* data, int N){ int i; float median; if (N == 1) { return data[0]; } // this will modify data qsort(data, N, sizeof*data, compare_floats); median = data[N/2-1]; if (EVENP(N)) { int mtype = STATISTIC_MEDIAN_BIAS; switch(mtype) { case -1: break; case 0: median += data[N/2]; median /=2; break; case 1: median = data[N/2]; break; default: fprintf(stderr,"bad STATISTIC_MEDIAN_BIAS %d", mtype); } } return median; }
// always fills-in a whole set of bytes, whose quantity is returned static int hex_string_to_bits(char *bits, char *string) { int nt = strlen(string); assert(EVENP(nt)); int cx = 0; for (int j = 0; j < nt; j += 2) { int c1 = string[j]; int c2 = string[j+1]; int nc1 = isdigit(c1) ? c1 - '0' : c1 - 'A' + 10; int nc2 = isdigit(c2) ? c2 - '0' : c2 - 'A' + 10; int nc = 16*nc1 + nc2; //fprintf(stderr, "<%02x>", nc); for (int i = 0; i < 8; i++) { bits[cx++] = GETBIT(nc, 7-i); //if (GETBIT(nc,7-i)) // fprintf(stderr, "X"); //else // fprintf(stderr, "."); } } return nt/2; }
int main(void) { int data = 0, d0, d1, d2, d3, parity, n; int facility, card; /* Skip the first 25 bits of data (make sure they are zeros) */ for (n = 0; n < 25; n++) { data = read_data(); if (data != 0) { /* Error */ printf("leading zeros expected\n"); } } /* Read in groups of 5-bits */ int start = 1; while (1) { /* The bits are sent LSB first */ d0 = read_data(); if (d0 == -1) { /* End of data */ break; } /* Read the rest of the data */ d1 = read_data(); d2 = read_data(); d3 = read_data(); parity = read_data(); if (d1 == -1 || d2 == -1 || d3 == -1 || parity == -1) { printf("premature end of data\n"); break; } /* Verify the parity bit (odd parity) */ if (EVENP(d0,d1,d2,d3,parity)) { printf("parity failure on 5-bit chunk\n"); } if (start) { /* The first segment should be 0xB == 1011B */ if (! (d0 & d1 & !d2 & d3) ) { /* Invalid starting segment */ printf("invalid start segment %d %d %d %d\n", d0, d1, d2, d3); } } else { /* Check for the ending segment 0xF == 1111B */ if (d0 & d1 & d2 & d3) { /* End of data sequence, the LRC follows */ d0 = read_data(); d1 = read_data(); d2 = read_data(); d3 = read_data(); parity = read_data(); if (EVENP(d0,d1,d2,d3,parity)) { printf("LRC parity failure\n"); } /* The parity for LRC checks out, verify the actual LRC */ /* Consume the remaining zeros */ while (1) { data = read_data(); if (data == -1) { break; } if (data != 0) { printf("trailing data must be zeros\n"); } } break; } if (d3 != 0) { printf("data segments must have zero padding\n"); } /* Otherwise this is a chunk of card data. Store it in a circular * buffer of 26 bits, so when we are finished iterating we are * left with the last 26 bits of input data (rest is discarded) */ printf("%d%d%d\n", d2, d1, d0); store_data(d2); store_data(d1); store_data(d0); } start = 0; } /* Check the data parity (first and last bit */ /* Dump the data */ for (n = 1; n < BUFLEN-1; n++) { printf("%d", buffer[(bufferPos+n) % BUFLEN]); } printf("\n"); /* Extract the facility ID */ facility = convert_binary(1, 8); printf("%d\n", facility); card = convert_binary(9, 16); printf("%d\n", card); }