diff options
Diffstat (limited to 'src/vu-from-image.c')
| -rw-r--r-- | src/vu-from-image.c | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/src/vu-from-image.c b/src/vu-from-image.c deleted file mode 100644 index 9c2d047..0000000 --- a/src/vu-from-image.c +++ /dev/null @@ -1,273 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "util.h" - -#include <arpa/inet.h> -#include <sys/wait.h> -#include <inttypes.h> -#include <string.h> -#include <unistd.h> - -USAGE("[-h] [-f | -p]") - -static char buf[BUFSIZ]; -static char width[3 * sizeof(size_t) + 1] = {0}; -static char height[3 * sizeof(size_t) + 1] = {0}; -static const char *conv_fail_msg = "convertion failed, if converting a farbfeld file, try -f"; -static size_t pixel_size; -static double value_max; -static double (*get_value)(char **bufp); -static void (*convert)(size_t n); -static int with_alpha = 1; -static int with_colour = 1; - -static double -get_value_u8(char** bufp) -{ - uint8_t value = *(uint8_t *)(*bufp); - *bufp += 1; - return value / value_max; -} - -static double -get_value_u16(char** bufp) -{ - uint16_t value = ntohs(*(uint16_t *)(*bufp)); - *bufp += 2; - return value / value_max; -} - -static double -get_value_u32(char** bufp) -{ - uint32_t value = ntohl(*(uint32_t *)(*bufp)); - *bufp += 4; - return value / value_max; -} - -static double -get_value_u64(char** bufp) -{ - uint64_t value; - value = (uint64_t)(buf[0]) << 56; - value |= (uint64_t)(buf[1]) << 48; - value |= (uint64_t)(buf[2]) << 40; - value |= (uint64_t)(buf[3]) << 32; - value |= (uint64_t)(buf[4]) << 24; - value |= (uint64_t)(buf[5]) << 16; - value |= (uint64_t)(buf[6]) << 8; - value |= (uint64_t)(buf[7]); - *bufp += 8; - return value / value_max; -} - -static void -from_srgb(size_t n) -{ - double red, green, blue, pixel[4]; - size_t ptr; - char *p; - for (ptr = 0; ptr + pixel_size <= n; ptr += pixel_size) { - p = buf + ptr; - red = srgb_decode(get_value(&p)); - green = with_colour ? srgb_decode(get_value(&p)) : red; - blue = with_colour ? srgb_decode(get_value(&p)) : red; - pixel[3] = with_alpha ? get_value(&p) : 1; - srgb_to_ciexyz(red, green, blue, pixel + 0, pixel + 1, pixel + 2); - ewriteall(STDOUT_FILENO, pixel, sizeof(pixel), "<stdout>"); - } -} - -static size_t -farbfeld_head(int fd, const char *fname) -{ - if (ereadall(fd, buf, 16, fname) != 16) - eprintf("%s\n", conv_fail_msg); - if (memcmp(buf, "farbfeld", 8)) - eprintf("%s\n", conv_fail_msg); - sprintf(width, "%"PRIu32, ntohl(*(uint32_t *)(buf + 8))); - sprintf(height, "%"PRIu32, ntohl(*(uint32_t *)(buf + 12))); - pixel_size = 4 * sizeof(uint16_t); - value_max = UINT16_MAX; - get_value = get_value_u16; - convert = from_srgb; - return 0; -} - -static size_t -pam_head(int fd, const char *fname) -{ - size_t ptr; - char *p; - unsigned long long int maxval = UINT8_MAX; - for (ptr = 0;;) { - ptr += ereadall(fd, buf + ptr, (size_t)buf - ptr, fname); - for (;;) { - p = memchr(buf, '\n', ptr); - if (!p) { - if (ptr == sizeof(buf)) - eprintf("%s\n", conv_fail_msg); - break; - } - *p++ = '\0'; - if (strstr(buf, "WIDTH ") == buf) { - if (*width || !buf[6] || strlen(buf + 6) >= sizeof(width)) - eprintf("%s\n", conv_fail_msg); - strcpy(width, buf + 6); - } else if (strstr(buf, "HEIGHT ") == buf) { - if (*height || !buf[7] || strlen(buf + 7) >= sizeof(height)) - eprintf("%s\n", conv_fail_msg); - strcpy(height, buf + 7); - } else if (strstr(buf, "MAXVAL ") == buf) { - if (tollu(buf + 7, 0, UINT64_MAX, &maxval)) { - if (errno != ERANGE) - eprintf("%s\n", conv_fail_msg); - eprintf("image uses greater colour resolution than supported\n"); - } else if (!maxval) { - eprintf("%s\n", conv_fail_msg); - } - } else if (strstr(buf, "TUPLTYPE ") == buf) { - if (!strcmp(buf, "TUPLTYPE BLACKANDWHITE")) - maxval = 1, with_colour = 0, with_alpha = 0; - else if (!strcmp(buf, "TUPLTYPE BLACKANDWHITE_ALPHA")) - maxval = 1, with_colour = 0, with_alpha = 1; - else if (!strcmp(buf, "TUPLTYPE GRAYSCALE")) - with_colour = 0, with_alpha = 0; - else if (!strcmp(buf, "TUPLTYPE GRAYSCALE_ALPHA")) - with_colour = 0, with_alpha = 1; - else if (!strcmp(buf, "TUPLTYPE RGB")) - with_colour = 1, with_alpha = 0; - else if (!strcmp(buf, "TUPLTYPE RGB_ALPHA")) - with_colour = 1, with_alpha = 1; - else - eprintf("image uses an unsupported tuple type: %s\n", buf + sizeof("TUPLTYPE")); - } else if (!strcmp(buf, "ENDHDR")) { - memmove(buf, p, ptr -= (size_t)(p - buf)); - goto header_done; - } - memmove(buf, p, ptr -= (size_t)(p - buf)); - } - } -header_done: - if (maxval < (size_t)UINT8_MAX) { - pixel_size = sizeof(uint8_t); - get_value = get_value_u8; - } else if (maxval < (size_t)UINT16_MAX) { - pixel_size = sizeof(uint16_t); - get_value = get_value_u16; - } else if (maxval < (size_t)UINT32_MAX) { - pixel_size = sizeof(uint32_t); - get_value = get_value_u32; - } else { - pixel_size = sizeof(uint64_t); - get_value = get_value_u64; - } - value_max = maxval; - pixel_size *= (with_colour ? 3 : 1) + with_alpha; - convert = from_srgb; - return ptr; -} - -int -main(int argc, char *argv[]) -{ - int status, pipe_rw[2], i, old_fd, forked = 0; - int headless = 0, farbfeld = 0, pam = 0; - pid_t pid = 0; - size_t off, n; - ssize_t r; - const char *file = "<subprocess>"; - const char *conv_fail_msg = "convertion failed, if converting a farbfeld file, try -f"; - - ARGBEGIN { - case 'f': - farbfeld = 1; - break; - case 'h': - headless = 1; - break; - case 'p': - pam = 1; - break; - default: - usage(); - } ARGEND; - - if (argc || (farbfeld && pam)) - usage(); - - if (farbfeld) - conv_fail_msg = "not a valid farbfeld file, try without -f"; - else if (pam) - conv_fail_msg = "not a valid RGBA portable arbitrary map file, try without -p"; - else - forked = 1; - - if (forked) { - file = "<stdin>"; - pipe_rw[0] = STDIN_FILENO; - goto after_fork; - } - - if (pipe(pipe_rw)) - eprintf("pipe:"); - if (pipe_rw[0] == STDIN_FILENO || pipe_rw[1] == STDIN_FILENO) - eprintf("no stdin open\n"); - if (pipe_rw[0] == STDOUT_FILENO || pipe_rw[1] == STDOUT_FILENO) - eprintf("no stdout open\n"); - for (i = 0; i < 2; i++) { - if (pipe_rw[i] == STDERR_FILENO) { - pipe_rw[i] = dup(old_fd = pipe_rw[i]); - if (pipe_rw[i] < 0) - eprintf("dup:"); - close(old_fd); - } - } - - pid = fork(); - if (pid < 0) - eprintf("fork:"); - - if (!pid) { - close(pipe_rw[0]); - if (dup2(pipe_rw[1], STDOUT_FILENO) == -1) - eprintf("dup2:"); - close(pipe_rw[1]); - /* XXX Is there a way to convert directly to raw XYZ? (Would avoid gamut truncation) */ - execlp("convert", "convert", "-", "-depth", "32", "-alpha", "activate", "pam:-", NULL); - eprintf("exec convert:"); - } - - close(pipe_rw[1]); -after_fork: - - if (farbfeld) - n = farbfeld_head(pipe_rw[0], file); - else - n = pam_head(pipe_rw[0], file); - - if (!*width || !*height) - eprintf("%s\n", conv_fail_msg); - - if (!headless) { - printf("1 %s %s xyza\n%cuivf", width, height, 0); - efflush(stdout, "<stdout>"); - } - - for (;;) { - convert(n); - off = n - (n % pixel_size); - memmove(buf, buf + off, n -= off); - r = read(pipe_rw[0], buf + n, sizeof(buf) - n); - if (r < 0) - eprintf("read %s:", file); - if (r == 0) - break; - n += (size_t)r; - } - - if (!forked) - return 0; - close(pipe_rw[0]); - while (waitpid(pid, &status, 0) != pid); - return !!status; -} |
