commit bcac04b4316d64063e743e7a49195173a0c175a0
Author: Mattias Andrée <maandree_AT_kth.se>
AuthorDate: Sun Sep 24 01:26:08 2017 +0200
Commit: Mattias Andrée <maandree_AT_kth.se>
CommitDate: Sun Sep 24 01:31:31 2017 +0200
Add -% to blind-to-text, blind-colour-srgb, and blind-colour-ciexyz
Signed-off-by: Mattias Andrée <maandree_AT_kth.se>
diff --git a/TODO b/TODO
index abb4cb4..b0bbde7 100644
--- a/TODO
+++ b/TODO
_AT_@ -35,8 +35,6 @@ blind-preview a graphical tool for previewing the output of a pipeline
should have sliders to tune environment variables
--- tool from creating blockwise transitions
-blind-to-text, blind-from-text: support %a, %e, %g, and custom precision
-
Add [-j jobs] to blind-from-video, blind-to-video, blind-convert, and blind-apply-kernel.
long double is slightly faster than long.
diff --git a/man/blind-colour-ciexyz.1 b/man/blind-colour-ciexyz.1
index ad1d8ef..01a9625 100644
--- a/man/blind-colour-ciexyz.1
+++ b/man/blind-colour-ciexyz.1
_AT_@ -3,6 +3,8 @@
blind-colour-ciexyz - Convert CIE XYZ for use with blind-single-colour(1)
.SH SYNOPSIS
.B blind-colour-ciexyz
+[-%
+.IR format ]
.RI ( X
.I Y
.I Z
_AT_@ -21,6 +23,42 @@ that colour model. If only
is specified, the colour will be CIE Standard Illuminant D65-grey
with a luminosity of
.IR Y .
+.SH OPTIONS
+.TP
+.BR -% \ \fIformat\fP
+Selects in what format parameters are printed.
+.I format
+may include the prefix
+.B +
+that specified that non-negative values should be prefixed with a
+.BR + .
+After any prefix, there may be a positive number specifying
+the percision of the output, optionally followed by either of
+the letters
+.BR a ,
+.BR e ,
+.BR f ,
+other
+.B g
+(other their synonymous uppercases),
+at most once, with the same semantics as in
+.BR printf (3).
+.B f
+is used if this letter is omitted.
+
+If ommited,
+.B 25f
+is used unless all three of
+.IR X ,
+.IR Y ,
+and
+.I Z
+is specified, in which case the parameters are
+printed as-is. This default is selected for ease
+of interoperability with other software, however,
+.B a
+is recommeded to improve performance and remove
+truncation error.
.SH SEE ALSO
.BR blind (7),
.BR blind-single-colour (1),
diff --git a/man/blind-colour-srgb.1 b/man/blind-colour-srgb.1
index c9b97fe..4934efa 100644
--- a/man/blind-colour-srgb.1
+++ b/man/blind-colour-srgb.1
_AT_@ -3,6 +3,8 @@
blind-colour-srgb - Convert sRGB for use with blind-single-colour(1) and blind-colour-matrix(1)
.SH SYNOPSIS
.B blind-colour-srgb
+[-%
+.IR format ]
[-d
.IR depth ]
[-l]
_AT_@ -38,6 +40,35 @@ unsigned integer with
bits.
.SH OPTIONS
.TP
+.BR -% \ \fIformat\fP
+Selects in what format parameters are printed.
+.I format
+may include the prefix
+.B +
+that specified that non-negative values should be prefixed with a
+.BR + .
+After any prefix, there may be a positive number specifying
+the percision of the output, optionally followed by either of
+the letters
+.BR a ,
+.BR e ,
+.BR f ,
+other
+.B g
+(other their synonymous uppercases),
+at most once, with the same semantics as in
+.BR printf (3).
+.B f
+is used if this letter is omitted.
+
+If ommited,
+.B 25f
+is used. This default is selected for ease of
+interoperability with other software, however,
+.B a
+is recommeded to improve performance and remove
+truncation error.
+.TP
.BR -d " "\fIdepth\fP
If all three parameters are
.RI 2^ depth -1,
diff --git a/man/blind-to-text.1 b/man/blind-to-text.1
index 4fe9b46..fdfa4f3 100644
--- a/man/blind-to-text.1
+++ b/man/blind-to-text.1
_AT_@ -3,6 +3,8 @@
blind-to-text - Convert a video to text
.SH SYNOPSIS
.B blind-to-text
+[-%
+.IR format ]
.SH DESCRIPTION
.B blind-to-text
reads a video from stdin and prints it
_AT_@ -36,6 +38,43 @@ line, after the head, where the second
frame begins. The pixels are printed
from left to right, from top to bottom,
and from first frame to last frame.
+.SH OPTIONS
+.TP
+.BR -% \ \fIformat\fP
+Selects in what format parameters are printed.
+.I format
+may include the prefix
+.B +
+that specified that non-negative values should be prefixed with a
+.BR + .
+After any prefix, there may be a positive number specifying
+the percision of the output, optionally followed by either of
+the letters
+.BR a ,
+.BR e ,
+.BR f ,
+other
+.B g
+(other their synonymous uppercases),
+or if the input is integer typed,
+.B d
+or
+.BR i ,
+at most once, with the same semantics as in
+.BR printf (3).
+.B f
+is used if this letter is omitted.
+The percision must be omitted the input is integer typed.
+
+If ommited,
+.B 25f
+or
+.B i
+is used. These defaults are selected for ease of
+interoperability with other software, however,
+.B a
+is recommeded to improve performance and remove
+truncation error.
.SH SEE ALSO
.BR blind (7),
.BR blind-from-text (1),
diff --git a/src/blind-colour-ciexyz.c b/src/blind-colour-ciexyz.c
index 9710074..17dec5a 100644
--- a/src/blind-colour-ciexyz.c
+++ b/src/blind-colour-ciexyz.c
_AT_@ -1,20 +1,34 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("(X Y Z | Y)")
+USAGE("[-% format] (X Y Z | Y)")
int
main(int argc, char *argv[])
{
double X, Y, Z;
+ const char *fmt = NULL;
- UNOFLAGS(0);
+ ARGBEGIN {
+ case '%':
+ fmt = UARGF();
+ break;
+ default:
+ usage();
+ } ARGEND;
if (argc == 1) {
+ fmt = select_print_format("%! %! %!\n", DOUBLE, fmt);
Y = etolf_arg("the Y value", argv[0]);
X = Y * D65_XYZ_X;
Z = Y * D65_XYZ_Z;
- printf("%.50lf %.50lf %.50lf\n", X, Y, Z);
+ printf(fmt, X, Y, Z);
+ } else if (argc == 3 && fmt) {
+ fmt = select_print_format("%! %! %!\n", DOUBLE, fmt);
+ X = etolf_arg("the X value", argv[0]);
+ Y = etolf_arg("the Y value", argv[1]);
+ Z = etolf_arg("the Z value", argv[2]);
+ printf(fmt, X, Y, Z);
} else if (argc == 3) {
printf("%s %s %s\n", argv[0], argv[1], argv[2]);
} else {
diff --git a/src/blind-colour-srgb.c b/src/blind-colour-srgb.c
index e5d1925..c7a5d91 100644
--- a/src/blind-colour-srgb.c
+++ b/src/blind-colour-srgb.c
_AT_@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-d depth] [-l] red green blue")
+USAGE("[-% format] [-d depth] [-l] red green blue")
int
main(int argc, char *argv[])
_AT_@ -9,6 +9,7 @@ main(int argc, char *argv[])
unsigned long long int max;
double red, green, blue, X, Y, Z;
int depth = 8, linear = 0;
+ const char *fmt = NULL;
ARGBEGIN {
case 'd':
_AT_@ -17,6 +18,9 @@ main(int argc, char *argv[])
case 'l':
linear = 1;
break;
+ case '%':
+ fmt = UARGF();
+ break;
default:
usage();
} ARGEND;
_AT_@ -24,6 +28,8 @@ main(int argc, char *argv[])
if (argc != 3)
usage();
+ fmt = select_print_format("%! %! %!\n", DOUBLE, fmt);
+
max = 1ULL << (depth - 1);
max |= max - 1;
red = etolf_arg("the red value", argv[0]) / (double)max;
_AT_@ -36,7 +42,7 @@ main(int argc, char *argv[])
}
srgb_to_ciexyz(red, green, blue, &X, &Y, &Z);
- printf("%.50lf %.50lf %.50lf\n", X, Y, Z);
+ printf(fmt, X, Y, Z);
efshut(stdout, "<stdout>");
return 0;
}
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index befa3c7..b4f977c 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
_AT_@ -3,7 +3,9 @@
#define INCLUDE_UINT16
#include "common.h"
-USAGE("")
+USAGE("[-% format]")
+
+const char *fmt = NULL;
#define FILE "blind-to-text.c"
#include "define-functions.h"
_AT_@ -14,10 +16,19 @@ main(int argc, char *argv[])
struct stream stream;
void (*process)(struct stream *stream, size_t n);
- UNOFLAGS(argc);
+ ARGBEGIN {
+ case '%':
+ fmt = UARGF();
+ break;
+ default:
+ usage();
+ } ARGEND;
- eopen_stream(&stream, NULL);
+ if (argc)
+ usage();
+ eopen_stream(&stream, NULL);
+ fmt = select_print_format("%! %! %! %!\n", stream.encoding, fmt);
SELECT_PROCESS_FUNCTION(&stream);
printf("%zu %zu %zu %s\n", stream.frames, stream.width, stream.height, stream.pixfmt);
process_stream(&stream, process);
_AT_@ -32,12 +43,10 @@ PROCESS(struct stream *stream, size_t n)
{
size_t i;
TYPE *p = (TYPE *)(stream->buf);
- for (i = 0, n /= stream->chan_size; i < n; i++)
-#ifdef INTEGER_TYPE
- printf("%"PRINT_TYPE"%c", (PRINT_CAST)(p[i]), (i + 1) % stream->n_chan ? ' ' : '\n');
-#else
- printf("%.25"PRINT_TYPE"%c", (PRINT_CAST)(p[i]), (i + 1) % stream->n_chan ? ' ' : '\n');
-#endif
+ for (i = 0, n /= stream->chan_size; i < n; i += 4) {
+ printf(fmt, (PRINT_CAST)(p[i + 0]), (PRINT_CAST)(p[i + 1]),
+ (PRINT_CAST)(p[i + 2]), (PRINT_CAST)(p[i + 3]));
+ }
}
#endif
diff --git a/src/define-functions.h b/src/define-functions.h
index 029265e..82d59a7 100644
--- a/src/define-functions.h
+++ b/src/define-functions.h
_AT_@ -4,13 +4,11 @@
# define PROCESS process_lf
# define TYPE double
# define SCAN_TYPE "lf"
-# define PRINT_TYPE "lf"
# define PRINT_CAST double
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
#endif
_AT_@ -18,13 +16,11 @@
# define PROCESS process_f
# define TYPE float
# define SCAN_TYPE "f"
-# define PRINT_TYPE "lf"
# define PRINT_CAST double
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
#endif
_AT_@ -32,13 +28,11 @@
# define PROCESS process_llf
# define TYPE long double
# define SCAN_TYPE "Lf"
-# define PRINT_TYPE "Lf"
# define PRINT_CAST long double
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
#endif
_AT_@ -46,14 +40,12 @@
# define PROCESS process_u8
# define TYPE uint8_t
# define SCAN_TYPE SCNu8
-# define PRINT_TYPE "u"
# define PRINT_CAST unsigned
# define INTEGER_TYPE
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
# undef INTEGER_TYPE
#endif
_AT_@ -62,14 +54,12 @@
# define PROCESS process_u16
# define TYPE uint16_t
# define SCAN_TYPE SCNu16
-# define PRINT_TYPE "u"
# define PRINT_CAST unsigned
# define INTEGER_TYPE
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
# undef INTEGER_TYPE
#endif
_AT_@ -78,14 +68,12 @@
# define PROCESS process_u32
# define TYPE uint32_t
# define SCAN_TYPE SCNu32
-# define PRINT_TYPE PRIu32
# define PRINT_CAST uint32_t
# define INTEGER_TYPE
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
# undef INTEGER_TYPE
#endif
_AT_@ -94,14 +82,12 @@
# define PROCESS process_u64
# define TYPE uint64_t
# define SCAN_TYPE SCNu64
-# define PRINT_TYPE PRIu64
# define PRINT_CAST uint64_t
# define INTEGER_TYPE
# include FILE
# undef PROCESS
# undef TYPE
# undef SCAN_TYPE
-# undef PRINT_TYPE
# undef PRINT_CAST
# undef INTEGER_TYPE
#endif
diff --git a/src/stream.c b/src/stream.c
index d2b1158..a0241b1 100644
--- a/src/stream.c
+++ b/src/stream.c
_AT_@ -369,6 +369,160 @@ get_pixel_format(const char *specified, const char *current)
}
+const char *
+nselect_print_format(int status, const char *format, enum encoding encoding, const char *fmt)
+{
+ static char retbuf[512];
+ int with_plus = 0, inttyped = -1;
+ const char *f = "", *orig = fmt;
+ char *proto = alloca((fmt ? strlen(fmt) : 0) + sizeof("%+#.50llx")), *p;
+ char *ret = retbuf;
+ size_t n, len;
+
+ if (!orig)
+ goto check_done;
+
+ for (; *fmt == '+'; fmt++)
+ with_plus = 1;
+ f = fmt + strspn(fmt, "0123456789");
+ if (f[0] && f[1])
+ enprintf(status, "invalid format: %s\n", orig);
+
+ switch (*f) {
+ case '\0':
+ inttyped = -1;
+ break;
+ case 'd': case 'i':
+ inttyped = 1;
+ break;
+ case 'a': case 'A':
+ case 'e': case 'E':
+ case 'f': case 'F':
+ case 'g': case 'G':
+ inttyped = 0;
+ break;
+ default:
+ enprintf(status, "invalid format: %s\n", orig);
+ }
+
+ switch (encoding) {
+ case FLOAT:
+ case DOUBLE:
+ case LONG_DOUBLE:
+ if (inttyped == 1)
+ enprintf(status, "invalid format `%s' is incompatible with the video format\n", orig);
+ inttyped = 0;
+ break;
+ case UINT8:
+ case UINT16:
+ case UINT32:
+ case UINT64:
+ if (*f != *fmt)
+ enprintf(status, "invalid format: %s\n", orig);
+ if (inttyped == 0)
+ enprintf(status, "invalid format `%s' is incompatible with the video format\n", orig);
+ inttyped = 1;
+ break;
+ default:
+ abort();
+ }
+check_done:
+
+ p = proto;
+ *p++ = '%';
+ if (with_plus)
+ *p++ = '+';
+
+ if (orig && *f != *fmt) {
+ *p++ = '.';
+ p = stpncpy(p, fmt, (size_t)(f - fmt));
+ } else if (orig && inttyped && *f != 'a' && *f != 'A') {
+ *p++ = '.';
+ *p++ = '2';
+ *p++ = '5';
+ }
+
+ inttyped = 1;
+ switch (encoding) {
+ case FLOAT:
+ inttyped = 0;
+ break;
+ case DOUBLE:
+ *p++ = 'l';
+ inttyped = 0;
+ break;
+ case LONG_DOUBLE:
+ *p++ = 'L';
+ inttyped = 0;
+ break;
+ case UINT8:
+ fmt = PRIi8;
+ break;
+ case UINT16:
+ fmt = PRIi16;
+ break;
+ case UINT32:
+ fmt = PRIi32;
+ break;
+ case UINT64:
+ fmt = PRIi64;
+ break;
+ default:
+ abort();
+ }
+
+ if (inttyped)
+ while (*fmt == 'l')
+ *p++ = *fmt++;
+
+ switch (orig ? *f : '\0') {
+ case '\0':
+ *p++ = inttyped ? 'i' : 'f';
+ break;
+ case 'd': case 'i':
+ *p++ = 'i';
+ break;
+ case 'a': case 'A':
+ *p++ = 'a';
+ break;
+ case 'e': case 'E':
+ *p++ = 'e';
+ break;
+ case 'f': case 'F':
+ *p++ = 'f';
+ break;
+ case 'g': case 'G':
+ *p++ = 'g';
+ break;
+ }
+
+ *p = '\0';
+
+ len = strlen(proto);
+ for (n = 1, f = format; *f; f++) {
+ if (f[0] == '%' && f[1] == '!') {
+ f++;
+ n += len;
+ } else {
+ n++;
+ }
+ }
+
+ if (n > sizeof(retbuf))
+ ret = enmalloc(status, n);
+ for (p = ret, f = format; *f; f++) {
+ if (f[0] == '%' && f[1] == '!') {
+ f++;
+ p = stpcpy(p, proto);
+ } else {
+ *p++ = *f;
+ }
+ }
+
+ return ret;
+}
+
+
int
enread_segment(int status, struct stream *stream, void *buf, size_t n)
{
diff --git a/src/stream.h b/src/stream.h
index b36e4d3..9499bcf 100644
--- a/src/stream.h
+++ b/src/stream.h
_AT_@ -43,6 +43,7 @@
#define echeck_dimensions(...) encheck_dimensions(1, __VA_ARGS__)
#define echeck_dimensions_custom(...) encheck_dimensions_custom(1, __VA_ARGS__)
#define echeck_compat(...) encheck_compat(1, __VA_ARGS__)
+#define select_print_format(...) nselect_print_format(1, __VA_ARGS__)
#define eread_segment(...) enread_segment(1, __VA_ARGS__)
#define eread_frame(...) enread_frame(1, __VA_ARGS__)
#define eread_row(...) enread_row(1, __VA_ARGS__)
_AT_@ -128,6 +129,7 @@ void eninf_check_fd(int status, int fd, const char *file);
void encheck_dimensions(int status, const struct stream *stream, enum dimension dimensions, const char *prefix);
void encheck_compat(int status, const struct stream *a, const struct stream *b);
const char *get_pixel_format(const char *specified, const char *current);
+const char *nselect_print_format(int status, const char *format, enum encoding encoding, const char *fmt);
int enread_segment(int status, struct stream *stream, void *buf, size_t n);
size_t ensend_frames(int status, struct stream *stream, int outfd, size_t frames, const char *outfname);
size_t ensend_rows(int status, struct stream *stream, int outfd, size_t rows, const char *outfname);
diff --git a/src/util.c b/src/util.c
index 41d8104..1f0da6a 100644
--- a/src/util.c
+++ b/src/util.c
_AT_@ -6,6 +6,7 @@ char *argv0;
void
weprintf(const char *fmt, ...)
{
+ char end;
va_list ap;
va_start(ap, fmt);
_AT_@ -14,9 +15,12 @@ weprintf(const char *fmt, ...)
vfprintf(stderr, fmt, ap);
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ end = *fmt ? strchr(fmt, '\0')[-1] : '\n';
+ if (end == ':') {
fputc(' ', stderr);
perror(NULL);
+ } else if (end != '\n') {
+ fputc('\n', stderr);
}
va_end(ap);
Received on Sun Sep 24 2017 - 01:32:35 CEST
This archive was generated by hypermail 2.3.0
: Sun Sep 24 2017 - 01:36:22 CEST