/* mark nodal domain containing grid[i][j] as counted non-recursive version inputs: grid - 2d array of function values counted - 2d array indicating whether a point has been counted i - row of initial point in grid j - column of initial point in grid nd - number of current nodal domain ny - rows in grid nx - columns in grid precondition: grid and counted are ny x nx outputs: return value: area of domain (in pixels) updates stats */ int findDomainNoInterp(double **grid, bit_array_t *counted, int i, int j, int nd, int ny, int nx) { stack *s = newStack(); push(s, j, i); bit_array_set(counted, j, i); int x, y; int currentSign; int size = 0; while (pop(s, &x, &y)) { size++; currentSign = SIGN(grid[i][j]); // orthongal directions // left if (x >= 1 && !bit_array_get(counted, x-1, y)) { if (SIGN(grid[y][x-1]) == currentSign) { bit_array_set(counted, x-1, y); push(s, x - 1, y); } } // above if (y >= 1 && !bit_array_get(counted, x, y-1)) { if (SIGN(grid[y-1][x]) == currentSign) { bit_array_set(counted, x, y-1); push(s, x, y-1); } } // right if (x < nx-1 && !bit_array_get(counted, x+1, y)) { if (SIGN(grid[y][x+1]) == currentSign) { bit_array_set(counted, x+1, y); push(s, x+1, y); } } // below if (y < ny-1 && !bit_array_get(counted, x, y+1)) { if (SIGN(grid[y+1][x]) == currentSign) { bit_array_set(counted, x, y+1); push(s, x, y+1); } } } destroyStack(s); return size; }
/* mark nodal domain containing grid[i][j] as counted non-recursive version inputs: grid - 2d array of function values counted - 2d array indicating whether a point has been counted i - row of initial point in grid j - column of initial point in grid nd - number of current nodal domain ny - rows in grid nx - columns in grid precondition: grid and counted are ny x nx outputs: return value: area of domain (in pixels) updates stats */ int findDomain(bit_array_t *signs, bit_array_t *counted, int i, int j, int nd, int ny, int nx) { stack *s = newStack(); push(s, j, i); bit_array_set(counted, j, i); int x, y; int currentSign; int size = 0; while (pop(s, &x, &y)) { size++; currentSign = bit_array_get(signs, j, i); #ifdef DEBUG domain_numbers[y][x] = nd; #endif // orthongal directions // left if (x >= 1 && !bit_array_get(counted, x-1, y)) { if (bit_array_get(signs, x-1, y) == currentSign) { bit_array_set(counted, x-1, y); push(s, x - 1, y); } } // above if (y >= 1 && !bit_array_get(counted, x, y-1)) { if (bit_array_get(signs, x, y-1) == currentSign) { bit_array_set(counted, x, y-1); push(s, x, y-1); } } // right if (x < nx-1 && !bit_array_get(counted, x+1, y)) { if (bit_array_get(signs, x+1, y) == currentSign) { bit_array_set(counted, x+1, y); push(s, x+1, y); } } // below if (y < ny-1 && !bit_array_get(counted, x, y+1)) { if (bit_array_get(signs, x, y+1) == currentSign) { bit_array_set(counted, x, y+1); push(s, x, y+1); } } } destroyStack(s); return size; }
/* find next unseen value of grid precondition: *i and *j nonnull inputs: **counted - 2d array indiciating which points have been counted *i - row to start searching from *j - column to start searching from ny - rows in counted nx - columns in counted outputs: *i - row of next zero found *j - column of next zero found return value - boolean indicating whether something was found */ int findNextUnseen(bit_array_t *counted, int *i, int *j, int ny, int nx) { int r, c; for (r = *i ; r < ny ; r++) { for (c = 0 ; c < nx ; c++) { if (r == *i && c <= *j) continue; if (!bit_array_get(counted, c, r)) { *i = r; *j = c; return 1; } } } return 0; // all points have been seen }
/** * Load spam database from the supplied FILE. * * The current file format is as follows: * * # Comment * SHA1 <SHA-1> * ADDED <date> * END * * @returns the amount of entries loaded or -1 on failure. */ static G_GNUC_COLD gulong spam_load(FILE *f) { static const struct spam_item zero_item; struct spam_item item; char line[1024]; guint line_no = 0; bit_array_t tag_used[BIT_ARRAY_SIZE(NUM_SPAM_TAGS)]; gulong item_count = 0; g_assert(f); /* Reset state */ item = zero_item; bit_array_init(tag_used, NUM_SPAM_TAGS); while (fgets(line, sizeof line, f)) { const char *tag_name, *value; char *sp, *nl; spam_tag_t tag; line_no++; nl = strchr(line, '\n'); if (!nl) { /* * If the line is too long or unterminated the file is either * corrupt or was manually edited without respecting the * exact format. If we continued, we would read from the * middle of a line which could be the filename or ID. */ g_warning("spam_load(): " "line too long or missing newline in line %u", line_no); break; } *nl = '\0'; /* Skip comments and empty lines */ if (*line == '#' || *line == '\0') continue; sp = strchr(line, ' '); if (sp) { *sp = '\0'; value = &sp[1]; } else { value = strchr(line, '\0'); } tag_name = line; tag = spam_string_to_tag(tag_name); g_assert(UNSIGNED(tag) < UNSIGNED(NUM_SPAM_TAGS)); if (SPAM_TAG_UNKNOWN != tag && !bit_array_flip(tag_used, tag)) { g_warning("spam_load(): duplicate tag \"%s\" in entry in line %u", tag_name, line_no); continue; } switch (tag) { case SPAM_TAG_ADDED: { time_t t; t = date2time(value, tm_time()); if ((time_t) -1 == t) { item.damaged = TRUE; } } break; case SPAM_TAG_SHA1: { if (strlen(value) != SHA1_BASE32_SIZE) { item.damaged = TRUE; g_warning("spam_load(): SHA-1 has wrong length."); } else { const struct sha1 *raw; raw = base32_sha1(value); if (raw) item.sha1 = *raw; else item.damaged = TRUE; } } break; case SPAM_TAG_NAME: { if ('\0' == value[0]) { item.damaged = TRUE; g_warning("spam_load(): Missing filename pattern."); } else if (!utf8_is_valid_string(value)) { item.damaged = TRUE; g_warning("spam_load(): Filename pattern is not UTF-8."); } else { item.name = h_strdup(value); } } break; case SPAM_TAG_SIZE: { const char *endptr; guint64 u; int error; u = parse_uint64(value, &endptr, 10, &error); if (error) { item.damaged = TRUE; g_warning("spam_load(): Cannot parse SIZE: %s", value); } else { item.min_size = u; item.max_size = u; if ('-' == endptr[0]) { u = parse_uint64(&endptr[1], &endptr, 10, &error); if (error) { item.damaged = TRUE; g_warning("spam_load(): Cannot parse SIZE: %s", value); } if (u < item.min_size) { item.damaged = TRUE; g_warning("spam_load(): " "Maximum size below minimum size"); } else { item.max_size = u; } } } } break; case SPAM_TAG_END: if ( !bit_array_get(tag_used, SPAM_TAG_SHA1) && !bit_array_get(tag_used, SPAM_TAG_NAME) ) { g_warning("spam_load(): missing SHA1 or NAME tag"); item.damaged = TRUE; } if (!bit_array_get(tag_used, SPAM_TAG_ADDED)) { g_warning("spam_load(): missing ADDED tag"); item.damaged = TRUE; } item.done = TRUE; break; case SPAM_TAG_UNKNOWN: /* Ignore */ break; case NUM_SPAM_TAGS: g_assert_not_reached(); break; } if (item.done && !item.damaged) { if (bit_array_get(tag_used, SPAM_TAG_SHA1)) { spam_sha1_add(&item.sha1); item_count++; } if (bit_array_get(tag_used, SPAM_TAG_NAME)) { if (!bit_array_get(tag_used, SPAM_TAG_SIZE)) { item.min_size = 0; item.max_size = MAX_INT_VAL(filesize_t); } if ( spam_add_name_and_size(item.name, item.min_size, item.max_size) ) { item.damaged = TRUE; } else { item_count++; } } } if (item.damaged) { g_warning("Damaged spam entry in line %u: " "tag_name=\"%s\", value=\"%s\"", line_no, tag_name, value); } if (item.done) { /* Reset state */ HFREE_NULL(item.name); item = zero_item; bit_array_clear_range(tag_used, 0, NUM_SPAM_TAGS - 1U); } } spam_sha1_sync(); return item_count; }
extension_map_t * lnf_lookup_map(lnf_file_t *lnf_file, bit_array_t *ext ) { extension_map_t *map; lnf_map_list_t *map_list; int i = 0; int is_set = 0; int id = 0; int map_id = 0; // find whether the template already exist map_id = 0; map_list = lnf_file->lnf_map_list; if (map_list == NULL) { // first map map_list = malloc(sizeof(lnf_map_list_t)); if (map_list == NULL) { return NULL; } lnf_file->lnf_map_list = map_list; } else { if (bit_array_cmp(&(map_list->bit_array), ext) == 0) { return map_list->map; } map_id++; while (map_list->next != NULL ) { if (bit_array_cmp(&(map_list->bit_array), ext) == 0) { return map_list->map; } else { map_id++; map_list = map_list->next; } } map_list->next = malloc(sizeof(lnf_map_list_t)); if (map_list->next == NULL) { return NULL; } map_list = map_list->next; } // allocate memory potentially for all extensions map = malloc(sizeof(extension_map_t) + (lnf_file->max_num_extensions + 1) * sizeof(uint16_t)); if (map == NULL) { return NULL; } map_list->map = map; map_list->next = NULL; bit_array_init(&map_list->bit_array, lnf_file->max_num_extensions + 1); bit_array_copy(&map_list->bit_array, ext); map->type = ExtensionMapType; map->map_id = map_id; // set extension map according the bits set in ext structure id = 0; i = 0; while ( (is_set = bit_array_get(ext, id)) != -1 ) { // fprintf(stderr, "i: %d, bit %d, val: %d\n", i, id, is_set); if (is_set) map->ex_id[i++] = id; id++; } map->ex_id[i++] = 0; // determine size and align 32bits map->size = sizeof(extension_map_t) + ( i - 1 ) * sizeof(uint16_t); if (( map->size & 0x3 ) != 0 ) { map->size += (4 - ( map->size & 0x3 )); } map->extension_size = 0; i=0; while (map->ex_id[i]) { int id = map->ex_id[i]; map->extension_size += extension_descriptor[id].size; i++; } //Insert_Extension_Map(&instance->extension_map_list, map); Insert_Extension_Map(lnf_file->extension_map_list, map); AppendToBuffer(lnf_file->nffile, (void *)map, map->size); return map; }
int bit_array_unset(bit_array *ba, uint32_t index) { if(bit_array_get(ba, index)) return ba->bits[index / 8] &= ~(uint8_t)(1 << (index % 8)); return 0; }
int bit_array_set(bit_array *ba, uint32_t index) { if(bit_array_get(ba, index)) return 0; return ba->bits[index / 8] |= 1 << (index % 8); }