+ debugmsg("...state was only %d", state);
+ result = free_pics_head(result);
+ }
+
+ if (result) {
+ debugmsg("...allocated %d colors", result->colors);
+ }
+
+ return result;
+}
+
+/*
+ * The obscurely-named "convert" is provided by ImageMagick
+ */
+static PICS_HEAD *
+parse_img(const char *filename)
+{
+ size_t need = strlen(filename) + 256;
+ char *cmd = malloc(need);
+ FILE *pp;
+ char buffer[BUFSIZ];
+ char dummy[BUFSIZ];
+ bool okay = TRUE;
+ PICS_HEAD *result;
+ int pic_x = 0;
+ int pic_y = 0;
+ int width = in_curses ? COLS : 80;
+
+ _nc_SPRINTF(cmd, _nc_SLIMIT(need) "identify \"%s\"", filename);
+ if (quiet)
+ _nc_STRCAT(cmd, " 2>/dev/null", need);
+
+ logmsg("...opening pipe to %s", cmd);
+
+ result = typeCalloc(PICS_HEAD, 1);
+ how_much.head += sizeof(PICS_HEAD);
+
+ if ((pp = popen(cmd, "r")) != 0) {
+ if (fgets(buffer, sizeof(buffer), pp) != 0) {
+ size_t n = strlen(filename);
+ debugmsg2("...read %s", buffer);
+ 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 = (int) ((double) pic_x / aspect_ratio);
+ } else {
+ pic_x = pic_y = 0;
+ }
+ }
+ pclose(pp);
+ }
+ if (pic_x <= 0 || pic_y <= 0)
+ goto finish;
+
+ _nc_SPRINTF(cmd, _nc_SLIMIT(need)
+ "convert " "-resize %dx%d\\! " "-thumbnail %dx \"%s\" "
+ "-define txt:compliance=SVG txt:-",
+ pic_x, pic_y, width, filename);
+ if (quiet)
+ _nc_STRCAT(cmd, " 2>/dev/null", need);
+
+ logmsg("...opening pipe to %s", cmd);
+ 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) {
+ debugmsg2("[%5d] %s", count + 1, buffer);
+ if (strlen(buffer) > 160) { /* 80 columns would be enough */
+ okay = FALSE;
+ break;
+ }
+ if (count++ == 0) {
+ if (match_c(buffer,
+ "# ImageMagick pixel enumeration: %d,%d,%d,%s ",
+ &col, &row, &len, dummy)) {
+ result->name = strdup(filename);
+ result->wide = (short) col;
+ result->high = (short) row;
+
+ begin_c_values(256);
+
+ result->cells = typeCalloc(PICS_CELL, (size_t) (col * row));
+ how_much.cell += (sizeof(PICS_CELL) * (size_t) (col * row));
+ } else {
+ okay = FALSE;
+ break;
+ }
+ } else {
+ /* subsequent lines begin "col,row: (r,g,b,a) #RGB" */
+ int r, g, b, nocolor;
+ unsigned check;
+ char *t;
+ char *s = t = 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,%d) #%x ",
+ &col, &row,
+ &r, &g, &b, &nocolor,
+ &check)) {
+ int which, c;
+
+ if ((s - t) > 8) /* 6 hex digits vs 8 */
+ check /= 256;
+ if (r > MaxRGB ||
+ g > MaxRGB ||
+ b > MaxRGB ||
+ check != (unsigned) ((r << 16) | (g << 8) | b)) {
+ okay = FALSE;
+ break;
+ }
+ c = gather_c_values((int) check);
+ which = col + (row * result->wide);
+ result->cells[which].ch = ((in_curses ||
+ check == 0xffffff)
+ ? ' '
+ : '#');
+ if (c >= 0 && c < reading_last) {
+ result->cells[which].fg = c;
+ reading_ncols[c].count++;
+ } else {
+ result->cells[which].fg = -1;
+ }
+ } else {
+ okay = FALSE;
+ break;
+ }
+ }
+ }
+ finish_c_values(result);
+ pclose(pp);
+ if (okay) {
+ /* FIXME - is this trimming needed? */
+ for (len = result->colors; len > 3; len--) {
+ if (result->fgcol[len - 1].fgcol == 0) {
+ result->colors = len - 1;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ finish:
+ free(cmd);
+
+ if (!okay) {
+ result = free_pics_head(result);