+ pics = 0;
+ }
+ return pics;
+}
+
+static void
+begin_c_values(int size)
+{
+ reading_last = 0;
+ reading_size = size;
+ reading_ncols = typeCalloc(FG_NODE *, size + 1);
+ how_much.pair += (sizeof(FG_NODE *) * (size_t) size);
+}
+
+#if HAVE_TSEARCH
+static int
+compare_c_values(const void *p, const void *q)
+{
+ const FG_NODE *a = (const FG_NODE *) p;
+ const FG_NODE *b = (const FG_NODE *) q;
+ return (a->fgcol - b->fgcol);
+}
+
+#ifdef DEBUG_TSEARCH
+static void
+check_c_values(int ln)
+{
+ static int oops = 5;
+ FG_NODE **ft;
+ int n;
+ if (oops-- <= 0)
+ return;
+ for (n = 0; n < reading_last; ++n) {
+ if (reading_ncols[n] == 0)
+ continue;
+ ft = tfind(reading_ncols[n], &reading_ntree, compare_c_values);
+ if (ft != 0 && *ft != 0) {
+ if ((*ft)->fgcol != reading_ncols[n]->fgcol) {
+ logmsg("@%d, %d:%d (%d) %p %p fgcol %06X %06X", ln, n,
+ reading_last - 1,
+ reading_size,
+ (*ft), reading_ncols[n],
+ reading_ncols[n]->fgcol,
+ (*ft)->fgcol);
+ }
+ if ((*ft)->which != reading_ncols[n]->which) {
+ logmsg("@%d, %d:%d (%d) %p %p which %d %d", ln, n,
+ reading_last - 1,
+ reading_size,
+ (*ft), reading_ncols[n],
+ reading_ncols[n]->which,
+ (*ft)->which);
+ }
+ } else {
+ logmsg("@%d, %d:%d (%d) %p %p null %06X %d", ln, n,
+ reading_last - 1,
+ reading_size,
+ ft, reading_ncols[n],
+ reading_ncols[n]->fgcol,
+ reading_ncols[n]->which);
+ }
+ }
+}
+#else
+#define check_c_values(n) /* nothing */
+#endif
+#endif
+
+#undef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+static int
+gather_c_values(int fg)
+{
+ int found = -1;
+#if HAVE_TSEARCH
+ FG_NODE **ft;
+ FG_NODE *find = typeMalloc(FG_NODE, 1);
+
+ how_much.pair += sizeof(FG_NODE);
+ find->fgcol = fg;
+ find->which = 0;
+
+ check_c_values(__LINE__);
+ if ((ft = tfind(find, &reading_ntree, compare_c_values)) != 0) {
+ found = (*ft)->which;
+ } else {
+ if (reading_last + 1 >= reading_size) {
+ int more = ((MAX(reading_last, reading_size) + 2) * 3) / 2;
+ FG_NODE **p = typeRealloc(FG_NODE *, more, reading_ncols);
+ if (p == 0)
+ goto done;
+
+ /* FIXME - this won't reallocate pointers for tsearch */
+ how_much.pair -= (sizeof(FG_NODE *) * (size_t) reading_size);
+ how_much.pair += (sizeof(FG_NODE *) * (size_t) more);
+ reading_size = more;
+ reading_ncols = p;
+ memset(reading_ncols + reading_last, 0,
+ sizeof(FG_NODE *) * (size_t) (more - reading_last));
+ check_c_values(__LINE__);
+ }
+ reading_ncols[reading_last] = find;
+ find->which = (unsigned short) reading_last++;
+ if ((ft = tsearch(find, &reading_ntree, compare_c_values)) != 0) {
+ found = find->which;
+ check_c_values(__LINE__);
+ }
+ }
+#else
+ int n;
+
+ for (n = 0; n < reading_last; ++n) {
+ if (reading_ncols[n]->fgcol == fg) {
+ found = n;
+ break;
+ }
+ }
+ if (found < 0) {
+ FG_NODE *node = typeMalloc(FG_NODE, 1);
+ how_much.pair += sizeof(FG_NODE);
+ if (reading_last + 2 >= reading_size) {
+ int more = ((reading_last + 2) * 3) / 2;
+ FG_NODE **p = typeRealloc(FG_NODE *, more, reading_ncols);
+ if (p == 0)
+ goto done;
+
+ how_much.pair -= (sizeof(FG_NODE *) * reading_size);
+ how_much.pair += (sizeof(FG_NODE *) * more);
+ reading_size = more;
+ reading_ncols = p;
+ memset(reading_ncols + reading_last, 0,
+ sizeof(FG_NODE) * (more - reading_last));
+ }
+ node->fgcol = fg;
+ node->which = reading_last;
+ reading_ncols[reading_last] = node;
+ found = reading_last++;
+ }
+#endif
+ done:
+ return found;
+}
+
+static void
+finish_c_values(PICS_HEAD * head)
+{
+ head->colors = reading_last;
+ head->fgcol = reading_ncols;
+
+ reading_last = 0;
+ reading_size = 0;
+ reading_ncols = 0;
+}
+
+static void
+dispose_c_values(void)
+{
+ int n;
+#if HAVE_TSEARCH
+ if (reading_ntree != 0) {
+#if HAVE_TDESTROY
+ tdestroy(reading_ntree, free);
+#else
+ for (n = 0; n < reading_last; ++n) {
+ tdelete(reading_ncols[n], &reading_ntree, compare_c_values);
+ }
+#endif
+ reading_ntree = 0;
+ }
+#endif
+ if (reading_ncols != 0) {
+ for (n = 0; n < reading_last; ++n) {
+ free(reading_ncols[n]);
+ }
+ free(reading_ncols);
+ reading_ncols = 0;