void dicom_import(const char *dirpath) { DIR *dir; struct dirent *dirent; dicom_t dicom, *dptr; static UT_icd dicom_icd = {sizeof(dicom_t), NULL, NULL, NULL}; UT_array *all_files; int w, h, d; // Dimensions of the full data cube. int i; uint16_t *data; uvec4b_t *cube; // First we parse all the dicom images into a sorted array. // XXX: how to propery iter a directory? utarray_new(all_files, &dicom_icd); dir = opendir(dirpath); while ((dirent = readdir(dir))) { if (dirent->d_name[0] == '.') continue; asprintf(&dicom.path, "%s/%s", dirpath, dirent->d_name); dicom_load(dicom.path, &dicom, NULL, 0); CHECK(dicom.rows && dicom.columns); utarray_push_back(all_files, &dicom); } closedir(dir); utarray_sort(all_files, dicom_sort); // Read all the file data one by one into the data cube. w = dicom.columns; h = dicom.rows; d = utarray_len(all_files); data = calloc(w * h * d, 2); dptr = NULL; while( (dptr = (dicom_t*)utarray_next(all_files, dptr))) { i = utarray_eltidx(all_files, dptr); dicom_load(dptr->path, &dicom, (char*)&data[w * h * i], w * h * 2); free(dptr->path); } utarray_free(all_files); // Generate 4 * 8bit RGBA values. // XXX: we should maybe support voxel data in 2 bytes monochrome. cube = malloc(w * h * d * sizeof(*cube)); for (i = 0; i < w * h * d; i++) { cube[i] = uvec4b(255, 255, 255, clamp(data[i], 0, 255)); } free(data); // This could belong to the caller function. mesh_blit(goxel()->image->active_layer->mesh, cube, -w / 2, -h / 2, -d / 2, w, h, d); free(cube); }
void qubicle_import(const char *path) { FILE *file; int version, color_format, orientation, compression, vmask, mat_count; int i, j, r, index, len, w, h, d, pos[3], x, y, z; char buff[256]; uint32_t v; uvec4b_t *cube; const uint32_t CODEFLAG = 2; const uint32_t NEXTSLICEFLAG = 6; file = fopen(path, "r"); version = READ(uint32_t, file); (void)version; color_format = READ(uint32_t, file); (void)color_format; orientation = READ(uint32_t, file); (void)orientation; compression = READ(uint32_t, file); (void)compression; vmask = READ(uint32_t, file); (void)vmask; mat_count = READ(uint32_t, file); for (i = 0; i < mat_count; i++) { len = READ(uint8_t, file); r = fread(buff, len, 1, file); (void)r; w = READ(uint32_t, file); h = READ(uint32_t, file); d = READ(uint32_t, file); pos[0] = READ(int32_t, file); pos[1] = READ(int32_t, file); pos[2] = READ(int32_t, file); (void)pos; cube = calloc(w * h * d, sizeof(*cube)); if (compression == 0) { for (index = 0; index < w * h * d; index++) { v = READ(uint32_t, file); cube[index].uint32 = v; cube[index].a = cube[index].a ? 255 : 0; } } else { for (z = 0; z < d; z++) { index = 0; while (true) { v = READ(uint32_t, file); if (v == NEXTSLICEFLAG) { break; // Next z. } len = 1; if (v == CODEFLAG) { len = READ(uint32_t, file); v = READ(uint32_t, file); } for (j = 0; j < len; j++) { x = index % w; y = index / w; cube[x + y * w + z * w * h].uint32 = v; index++; } } } } mesh_blit(goxel()->image->active_layer->mesh, cube, pos[0], pos[1], pos[2], w, h, d); free(cube); } }