+/*
+ * The obscurely-named "convert" is provided by ImageMagick
+ */
+static PICS_HEAD *
+parse_img(const char *filename)
+{
+ char *cmd = malloc(strlen(filename) + 80);
+ FILE *pp;
+ char buffer[BUFSIZ];
+ bool failed = FALSE;
+ PICS_HEAD *result = typeCalloc(PICS_HEAD, 1);
+
+ sprintf(cmd, "convert -thumbnail %dx \"%s\" txt:-", COLS, filename);
+ if ((pp = popen(cmd, "r")) != 0) {
+ int count = 0;
+ int col = 0;
+ int row = 0;
+ int len = 0;
+ while (fgets(buffer, sizeof(buffer), pp) != 0) {
+ if (strlen(buffer) > 160) { /* 80 columns would be enough */
+ failed = TRUE;
+ break;
+ }
+ if (count++ == 0) {
+ if (match_c(buffer,
+ "# ImageMagick pixel enumeration: %d,%d,%d,srgba ",
+ &col, &row, &len)) {
+ result->name = strdup(filename);
+ result->wide = col;
+ result->high = row;
+ result->colors = 256;
+ result->pairs = typeCalloc(PICS_PAIR, result->colors);
+ result->cells = typeCalloc(PICS_CELL, (size_t) (col * row));
+ } else {
+ failed = TRUE;
+ break;
+ }
+ } else {
+ /* subsequent lines begin "col,row: (r,g,b,a) #RGB" */
+ int r, g, b;
+ unsigned check;
+ int which, c;
+ char *s = strchr(buffer, '#');
+ if (s != 0) {
+ /* after the "#RGB", there are differences - just ignore */
+ while (*s != '\0' && !isspace(UChar(*s)))
+ ++s;
+ *++s = '\0';
+ }
+ if (match_c(buffer,
+ "%d,%d: (%d,%d,%d,255) #%x ",
+ &col, &row,
+ &r, &g, &b,
+ &check)) {
+ if (r > 255 ||
+ g > 255 ||
+ b > 255 ||
+ check != (unsigned) ((r << 16) | (g << 8) | b)) {
+ failed = TRUE;
+ break;
+ }
+ for (c = 0; c < result->colors; ++c) {
+ if (result->pairs[c].fg == (int) check) {
+ break;
+ } else if (result->pairs[c].fg == 0) {
+ result->pairs[c].fg = (int) check;
+ break;
+ }
+ }
+ if (c >= result->colors) {
+ int more = (result->colors * 3) / 2;
+ PICS_PAIR *p = typeRealloc(PICS_PAIR, more, result->pairs);
+ if (p != 0) {
+ result->colors = more;
+ result->pairs = p;
+ result->pairs[c].fg = (int) check;
+ result->pairs[c].bg = 0;
+ while (++c < more) {
+ result->pairs[c].fg = 0;
+ result->pairs[c].bg = 0;
+ }
+ }
+ }
+ which = col + (row * result->wide);
+ result->cells[which].ch = '#'; /* TODO: space? */
+ result->cells[which].fg = (c < result->colors) ? c : -1;
+ } else {
+ failed = TRUE;
+ break;
+ }
+ }
+ }
+ pclose(pp);
+ if (!failed) {
+ for (len = result->colors; len > 3; len--) {
+ if (result->pairs[len - 1].fg == 0) {
+ result->colors = len - 1;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ free(cmd);
+
+ if (failed) {
+ free_pics_head(result);
+ result = 0;
+ }
+
+ return result;
+}
+