/* * testcompression.c - test compression schemes */ #include #include #include #include #include #include "cbf.h" #ifdef CBF_USE_LONG_LONG #ifndef LLONG_MAX #define LLONG_MAX (1ll << (sizeof(long long) * CHAR_BIT - 1)) #define ULLONG_MAX (~0ll) #endif #endif #define NSTEPS 5 double urand( void ) { return rand() * 1.0 / RAND_MAX; } #define DATAUC 0 #define DATASC 1 #define DATAUS 2 #define DATASS 3 #define DATAUI 4 #define DATASI 5 #define DATAUL 6 #define DATASL 7 #define DATAULL 8 #define DATASLL 9 #define DATAF 10 #define DATAD 11 /* * Create images where spots are separated by a uniform distribution of mean * distance of NSTEPS/2 and have height uniformly distributed over (positive * part of) data range */ static size_t createtestimage(void **data, int type, int nelem) { unsigned char *ucdata; signed char *scdata; unsigned short *usdata; signed short *ssdata; unsigned int *uidata; signed int *sidata; unsigned long *uldata; signed long *sldata; CBF_ull_type *ulldata; CBF_sll_type *slldata; float *fdata; double *ddata; int i = 0; size_t elsize = 0; switch (type) { case DATAUC: /* unsigned char */ ucdata = (unsigned char *)calloc(nelem, 1); elsize = sizeof(char); while (i < nelem) { ucdata[i] = urand() * UCHAR_MAX; i += 1 + urand() * NSTEPS; } *data = ucdata; break; case DATASC: /* signed char */ scdata = (signed char *)calloc(nelem, 1); elsize = sizeof(char); while (i < nelem) { scdata[i] = urand() * SCHAR_MAX; i += 1 + urand() * NSTEPS; } *data = scdata; break; case DATAUS: /* unsigned short */ usdata = (unsigned short *)calloc(nelem, sizeof(short)); elsize = sizeof(short); while (i < nelem) { usdata[i] = urand() * USHRT_MAX; i += 1 + urand() * NSTEPS; } *data = usdata; break; case DATASS: /* signed short */ ssdata = (signed short *)calloc(nelem, sizeof(short)); elsize = sizeof(short); while (i < nelem) { ssdata[i] = urand() * SHRT_MAX; i += 1 + urand() * NSTEPS; } *data = ssdata; break; case DATAUI: /* unsigned int */ uidata = (unsigned int *)calloc(nelem, sizeof(int)); elsize = sizeof(int); while (i < nelem) { uidata[i] = urand() * UINT_MAX; i += 1 + urand() * NSTEPS; } *data = uidata; break; case DATASI: /* signed int */ sidata = (signed int *)calloc(nelem, sizeof(int)); elsize = sizeof(int); while (i < nelem) { sidata[i] = urand() * INT_MAX; i += 1 + urand() * NSTEPS; } *data = sidata; break; case DATAUL: /* unsigned long */ uldata = (unsigned long *)calloc(nelem, sizeof(long)); elsize = sizeof(long); while (i < nelem) { uldata[i] = urand() * ULONG_MAX; i += 1 + urand() * NSTEPS; } *data = uldata; break; case DATASL: /* signed long */ sldata = (signed long *)calloc(nelem, sizeof(long)); elsize = sizeof(long); while (i < nelem) { sldata[i] = urand() * LONG_MAX; i += 1 + urand() * NSTEPS; } *data = sldata; break; #ifdef CBF_USE_LONG_LONG case DATAULL: /* unsigned long long */ ulldata = (unsigned long long *)calloc(nelem, sizeof(long long)); elsize = sizeof(long long); while (i < nelem) { ulldata[i] = urand() * ULLONG_MAX; i += 1 + urand() * NSTEPS; } *data = ulldata; break; case DATASLL: /* signed long long */ slldata = (signed long long *)calloc(nelem, sizeof(long long)); elsize = sizeof(long long); while (i < nelem) { slldata[i] = urand() * LLONG_MAX; i += 1 + urand() * NSTEPS; } *data = slldata; break; #else case DATAULL: /* unsigned long long as an array */ ulldata = (CBF_ull_type *)calloc(nelem, sizeof(CBF_ull_type)); elsize = sizeof(CBF_ull_type); while (i < nelem) { ulldata[i].el0 = urand() * INT_MAX; ulldata[i].el1 = urand() * INT_MAX; #if CBF_ULL_INTS == 4 ulldata[i].el2 = urand() * INT_MAX; ulldata[i].el3 = urand() * INT_MAX; #endif i += 1 + urand() * NSTEPS; } *data = ulldata; break; case DATASLL: /* signed long long */ slldata = (CBF_sll_type *)calloc(nelem, sizeof(CBF_sll_type)); elsize = sizeof(CBF_sll_type); while (i < nelem) { slldata[i].el0 = urand() * INT_MAX; slldata[i].el1 = urand() * INT_MAX; #if CBF_ULL_INTS == 4 slldata[i].el2 = urand() * INT_MAX; slldata[i].el3 = urand() * INT_MAX; #endif i += 1 + urand() * NSTEPS; } *data = slldata; break; #endif case DATAF: /* float */ fdata = (float *)calloc(nelem, sizeof(float)); elsize = sizeof(float); while (i < nelem) { fdata[i] = urand() * INT_MAX; i += 1 + urand() * NSTEPS; } *data = fdata; break; case DATAD: /* double */ ddata = (double *)calloc(nelem, sizeof(double)); elsize = sizeof(double); while (i < nelem) { ddata[i] = urand() * INT_MAX; i += 1 + urand() * NSTEPS; } *data = ddata; break; default: fprintf(stderr, "Unknown type number\n"); } return elsize; } static int createtestfile(const char *fn, int isreal, int rows, int columns, int compression, void *data, size_t elsize, int elsigned) { int status; cbf_handle ch; FILE *f; status = cbf_make_handle(&ch); if (status) printf("make_handle (%d)\n", status); status = cbf_new_datablock (ch, "image_1"); if (status) printf("new_datablock (%d)\n", status); status = cbf_new_category(ch, "array_data"); if (status) printf("new_category (%d)\n", status); status = cbf_new_column(ch, "array_id"); if (status) printf("new_column (%d)\n", status); status = cbf_set_value(ch, "image_1"); if (status) printf("set_value (%d)\n", status); status = cbf_new_column(ch, "binary_id"); if (status) printf("new_column (%d)\n", status); status = cbf_set_integervalue(ch, 1); if (status) printf("set_integervalue (%d)\n", status); status = cbf_new_column(ch, "data"); if (status) printf("new_column (%d)\n", status); if (isreal) { status = cbf_set_realarray_wdims(ch, compression, 1, data, elsize, rows * columns, "little_endian", columns, rows, 0, 0); if (status) printf("set_realarray_wdims (%d)\n", status); } else { status = cbf_set_integerarray_wdims(ch, compression, 1, data, elsize, elsigned, rows * columns, "little_endian", columns, rows, 0, 0); if (status) printf("set_integerarray_wdims (%d)\n", status); } if (status) return status; f = fopen(fn, "wb"); status = cbf_write_widefile(ch, f, 1, CBF, MIME_HEADERS | MSG_DIGEST, 0); if (status) printf("write_widefile (%d)\n", status); status = cbf_free_handle(ch); if (status) printf("free_handle (%d)\n", status); return status; } static size_t readtestimage(const char *fn, void **data, size_t *size, int *sign) { cbf_handle ch; int status; FILE *f; unsigned int cifcomp = 0; int bid = 0, els = 0, elu = 0; int minel = 0, maxel = 0, isre = 0; size_t elsize = 0, elnum = 0; size_t dim1 = 0, dim2 = 0, dim3 = 0, pad = 0; const char *byteorder = NULL; int isreal; int id; size_t rsize = 0; status = cbf_make_handle(&ch); if (status) printf("make_handle (%d)\n", status); f = fopen(fn, "rb"); status = cbf_read_widefile(ch, f, MSG_DIGEST); if (status) printf("read_widefile (%d)\n", status); status = cbf_rewind_datablock(ch); if (status) printf("rewind_db (%d)\n", status); status = cbf_find_category(ch, "array_data"); if (status) printf("find_cat (%d)\n", status); status = cbf_find_tag(ch, "_array_data.data"); if (status) printf("find_tag (%d)\n", status); status = cbf_rewind_row(ch); if (status) printf("rewind_row (%d)\n", status); status = cbf_get_arrayparameters_wdims(ch, &cifcomp, &bid, &elsize, &els, &elu, &elnum, &minel, &maxel, &isre, &byteorder, &dim1, &dim2, &dim3, &pad); if (status) printf("get_aparams (%d) = %d, %d, %ld, %d, %d,\n", status, cifcomp, bid, (long)elsize, els, elu); if (status) printf(" %ld, %d, %d, %d, %s,\n", (long)elnum, minel, maxel, isre, (byteorder == NULL) ? "null" : byteorder); if (status) printf(" %ld, %ld, %ld, %ld\n", (long)dim1, (long)dim2, (long)dim3, (long)pad); isreal = (isre == 1); if (isreal) { if (elsize == sizeof(float) || elsize == sizeof(double)) { void *rdata = malloc(elsize * elnum); status = cbf_get_realarray(ch, &id, rdata, elsize, elnum, &rsize); if (status) printf("get_realarray (%d)\n", status); *data = rdata; } else { fprintf(stderr, "Size of element (%ld) does not match any real types\n", (long)elsize); } } else { if (els && elu) { fprintf(stderr, "Both signed and unsigned flags have been set!\n"); return rsize; } if (elsize == sizeof(char) || elsize == sizeof(short) || elsize == sizeof(int) || elsize == sizeof(long) #ifdef CBF_USE_LONG_LONG || elsize == sizeof(long long) #else || elsize == sizeof(CBF_sll_type) #endif ) { void *idata = malloc(elsize * elnum); status = cbf_get_integerarray(ch, &id, idata, elsize, els, elnum, &rsize); if (status) printf("get_integerarray (%d)\n", status); *data = idata; } else { fprintf(stderr, "Size of element (%ld) does not match any integer types\n", (long)elsize); } } status = cbf_free_handle(ch); if (status) printf("free_handle (%d)\n", status); *sign = els; *size = elsize; if (rsize != elnum) printf("Read %ld elements\n", (long)rsize); return rsize; } static void checkdata(int type, int nelem, void *data, void *idata) { unsigned char *ucdata, *ucidata; signed char *scdata, *scidata; unsigned short *usdata, *usidata; signed short *ssdata, *ssidata; unsigned int *uidata, *uiidata; signed int *sidata, *siidata; unsigned long *uldata, *ulidata; signed long *sldata, *slidata; #ifdef CBF_USE_LONG_LONG unsigned long long *ulldata, *ullidata; signed long long *slldata, *sllidata; #else CBF_ull_type *ulldata, *ullidata; CBF_sll_type *slldata, *sllidata; #endif float *fdata, *fidata; double *ddata, *didata; int i = 0; switch (type) { case DATAUC: /* unsigned char */ ucdata = (unsigned char *)data; ucidata = (unsigned char *)idata; while (i < nelem) { if (ucdata[i] != ucidata[i]) { fprintf(stderr, "UC element %d did not match (%d != %d)\n", i, ucdata[i], ucidata[i]); fprintf(stderr, "Previous UC elements are (%x %x)\n", ucdata[i-1], ucidata[i-1]); fprintf(stderr, "Previous UC elements are ~(%x %x)\n", ~ucdata[i-1], ~ucidata[i-1]); return; } i++; } break; case DATASC: /* signed char */ scdata = (signed char *)data; scidata = (signed char *)idata; while (i < nelem) { if (scdata[i] != scidata[i]) { fprintf(stderr, "SC element %d did not match (%d != %d)\n", i, scdata[i], scidata[i]); fprintf(stderr, "Previous SC elements are (%x %x)\n", scdata[i-1], scidata[i-1]); fprintf(stderr, "Previous SC elements are ~(%x %x)\n", ~scdata[i-1], ~scidata[i-1]); return; } i++; } break; case DATAUS: /* unsigned short */ usdata = (unsigned short *)data; usidata = (unsigned short *)idata; while (i < nelem) { if (usdata[i] != usidata[i]) { fprintf(stderr, "US element %d did not match (%d != %d)\n", i, usdata[i], usidata[i]); return; } i++; } break; case DATASS: /* signed short */ ssdata = (signed short *)data; ssidata = (signed short *)idata; while (i < nelem) { if (ssdata[i] != ssidata[i]) { fprintf(stderr, "SS element %d did not match (%d != %d)\n", i, ssdata[i], ssidata[i]); return; } i++; } break; case DATAUI: /* unsigned int */ uidata = (unsigned int *)data; uiidata = (unsigned int *)idata; while (i < nelem) { if (uidata[i] != uiidata[i]) { fprintf(stderr, "UI element %d did not match (%d != %d)\n", i, uidata[i], uiidata[i]); return; } i++; } break; case DATASI: /* signed int */ sidata = (signed int *)data; siidata = (signed int *)idata; while (i < nelem) { if (sidata[i] != siidata[i]) { fprintf(stderr, "SI element %d did not match (%d != %d)\n", i, sidata[i], siidata[i]); return; } i++; } break; case DATAUL: /* unsigned long */ uldata = (unsigned long *)data; ulidata = (unsigned long *)idata; while (i < nelem) { if (uldata[i] != ulidata[i]) { fprintf(stderr, "UL element %d did not match (%ld != %ld)\n", i, uldata[i], ulidata[i]); return; } i++; } break; case DATASL: /* signed long */ sldata = (signed long *)data; slidata = (signed long *)idata; while (i < nelem) { if (sldata[i] != slidata[i]) { fprintf(stderr, "SL element %d did not match (%ld != %ld)\n", i, sldata[i], slidata[i]); return; } i++; } break; #ifdef CBF_USE_LONG_LONG case DATAULL: /* unsigned long long */ ulldata = (unsigned long long *)data; ullidata = (unsigned long long *)idata; while (i < nelem) { if (ulldata[i] != ullidata[i]) { fprintf(stderr, "ULL element %d did not match (%lld != %lld)\n", i, ulldata[i], ullidata[i]); return; } i++; } break; case DATASLL: /* signed long long */ slldata = (signed long long *)data; sllidata = (signed long long *)idata; while (i < nelem) { if (slldata[i] != sllidata[i]) { fprintf(stderr, "SLL element %d did not match (%lld != %lld)\n", i, slldata[i], sllidata[i]); return; } i++; } break; #else case DATAULL: /* unsigned long long */ ulldata = (CBF_ull_type *)data; ullidata = (CBF_ull_type *)idata; while (i < nelem) { #if CBF_ULL_INTS == 2 if (ulldata[i].el0 != ullidata[i].el0 || ulldata[i].el1 != ullidata[i].el1) { fprintf(stderr, "ULL element %d did not match (%x %x != %x %x)\n", i, ulldata[i].el1,ulldata[i].el0, ullidata[i].el1,ullidata[i].el0); return; } #else if (ulldata[i].el0 != ullidata[i].el0 || ulldata[i].el1 != ullidata[i].el1 || ulldata[i].el2 != ullidata[i].el2 || ulldata[i].el3 != ullidata[i].el3) { fprintf(stderr, "ULL element %d did not match (%x %x %x %x != %x %x %x %x)\n", i, ulldata[i].el3,ulldata[i].el2,ulldata[i].el1,ulldata[i].el0, ullidata[i].el3,ullidata[i].el2,ullidata[i].el1,ullidata[i].el0); return; } #endif i++; } break; case DATASLL: /* signed long long */ slldata = (CBF_sll_type *)data; sllidata = (CBF_sll_type *)idata; while (i < nelem) { #if CBF_SLL_INTS == 2 if (slldata[i].el0 != sllidata[i].el0 || slldata[i].el1 != sllidata[i].el1) { fprintf(stderr, "SLL element %d did not match (%x %x != %x %x)\n", i, slldata[i].el1,slldata[i].el0, sllidata[i].el1,sllidata[i].el0); return; } #else if (slldata[i].el0 != sllidata[i].el0 || slldata[i].el1 != sllidata[i].el1 || slldata[i].el2 != sllidata[i].el2 || slldata[i].el3 != sllidata[i].el3) { fprintf(stderr, "ULL element %d did not match (%x %x %x %x != %x %x %x %x)\n", i, ulldata[i].el3,ulldata[i].el2,ulldata[i].el1,ulldata[i].el0, ullidata[i].el3,ullidata[i].el2,ullidata[i].el1,ullidata[i].el0); return; } #endif i++; } break; #endif case DATAF: /* float */ fdata = (float *)data; fidata = (float *)idata; while (i < nelem) { if (fabs(fdata[i] - fidata[i]) > FLT_MIN) { fprintf(stderr, "F element %d did not match (%g != %g)\n", i, fdata[i], fidata[i]); return; } i++; } break; case DATAD: /* double */ ddata = (double *)data; didata = (double *)idata; while (i < nelem) { if (fabs(ddata[i] - didata[i]) > DBL_MIN) { fprintf(stderr, "D element %d did not match (%g != %g)\n", i, ddata[i], didata[i]); return; } i++; } break; } } static void testinteger(const char *fn, int rows, int cols, int type, int comp) { void *data, *idata; size_t elsize; size_t nelem = rows*cols; size_t isize; int isign; elsize = createtestimage(&data, type, nelem); if (elsize == 0) { fprintf(stderr, "Could not create test image\n"); return; } if (createtestfile(fn, 0, rows, cols, comp, data, elsize, type & 1) != 0) { fprintf(stderr, "Could not create test file\n"); return; } if (readtestimage(fn, &idata, &isize, &isign) != nelem) { fprintf(stderr, "Did not read %ld elements\n", (long) nelem); } if (isize != elsize) fprintf(stderr, "Size of elements does not match (%ld != %ld)\n", (long)elsize, (long)isize); if (isign != (type & 1)) fprintf(stderr, "Sign of elements does not match (%d != %d)\n", type & 1, isign); checkdata(type, nelem, data, idata); free(data); free(idata); } static void testreal(const char *fn, int rows, int cols, int type, int comp) { void *data, *idata; size_t elsize; size_t nelem = rows*cols; size_t isize; int isign; elsize = createtestimage(&data, type, nelem); if (elsize == 0) { fprintf(stderr, "Could not create test image\n"); return; } if (createtestfile(fn, 1, rows, cols, comp, data, elsize, 1) != 0) { fprintf(stderr, "Could not create test file\n"); return; } if (readtestimage(fn, &idata, &isize, &isign) != nelem) { fprintf(stderr, "Did not read %ld elements\n", (long) nelem); } if (isize != elsize) fprintf(stderr, "Size of elements does not match (%ld != %ld)\n", (long)elsize, (long)isize); checkdata(type, nelem, data, idata); free(data); free(idata); } static void testall(const char *fn) { int rows = 512; int cols = 10; int c, t; int comp[] = { CBF_NONE, /* CBF_PREDICTOR, not implemented! */ CBF_BYTE_OFFSET, CBF_NIBBLE_OFFSET, CBF_PACKED_V2, CBF_CANONICAL }; char * compstr[] = { "CBF_NONE", /* "CBF_PREDICTOR", */ "CBF_BYTE_OFFSET", "CBF_NIBBLE_OFFSET", "CBF_PACKED_V2", "CBF_CANONICAL" }; char * datastr[] = { "unsigned char", "signed char", "unsigned short", "signed short", "unsigned int", "signed int", "unsigned long", "signed long", #ifdef CBF_USE_LONG_LONG "unsigned long long", "signed long long", #else "CBF_ull_type", "CBF_sll_type", #endif "float", "double" }; for (c = 0; c < 5; c++) { printf("Testing compression scheme %d, %d %s\n", c, comp[c], compstr[c]); for (t = 0; t < DATAF; t++) { printf(" with data type %d, %s\n", t, datastr[t]); testinteger(fn, rows, cols, t, comp[c]); } printf(" with data type %d, %s\n", DATAF, datastr[DATAF]); testreal(fn, rows, cols, DATAF, comp[c]); printf(" with data type %d, %s\n", DATAD, datastr[DATAD]); testreal(fn, rows, cols, DATAD, comp[c]); } } int main(int argc, char **argv) { char *fn; if (argc < 2) fn = "CTC.cbf"; else fn = argv[1]; printf("Saving to %s\n", fn); testall(fn); return 0; }