+/*
+ * The obscurely-named "convert" is provided by ImageMagick
+ */
+static PICS_HEAD *
+parse_img(const char *filename)
+{
+ char *cmd = malloc(strlen(filename) + 256);
+ FILE *pp;
+ char buffer[BUFSIZ];
+ bool failed = FALSE;
+ PICS_HEAD *result = typeCalloc(PICS_HEAD, 1);
+ int pic_x = 0;
+ int pic_y = 0;
+ int width = in_curses ? COLS : 80;
+
+ sprintf(cmd, "identify \"%s\"", filename);
+
+ if ((pp = popen(cmd, "r")) != 0) {
+ if (fgets(buffer, sizeof(buffer), pp) != 0) {
+ size_t n = strlen(filename);
+ if (strlen(buffer) > n &&
+ !strncmp(buffer, filename, n) &&
+ isspace(UChar(buffer[n])) &&
+ sscanf(skip_word(buffer + n), " %dx%d ", &pic_x, &pic_y) == 2) {
+ /* distort image to make it show normally on terminal */
+ pic_x = (166 * pic_x) / 100;
+ } else {
+ pic_x = pic_y = 0;
+ }
+ }
+ pclose(pp);
+ }
+ if (pic_x <= 0 || pic_y <= 0)
+ goto finish;
+
+ sprintf(cmd, "convert -resize %dx%d\\! -thumbnail %dx \"%s\" txt:-",
+ pic_x, pic_y, width, 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 = ((in_curses ||
+ check == 0xffffff)
+ ? ' '
+ : '#');
+ 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;
+ }
+ }
+ }
+ }
+ finish:
+ free(cmd);
+
+ if (failed) {
+ free_pics_head(result);
+ result = 0;
+ }
+
+ return result;
+}
+