#include #include #include #include #include #define CHUNK_DEFAULT (0x1000) #define MIN(a, b) (a < b? a : b) #define MAX(a, b) (a > b? a : b) int usage(const char* progname) { fprintf(stderr, "usage: %s [-c chunk] [-m mul] [-s start] [-e end]\n", progname); return 1; } int main(int argc, char** argv) { int optch; int cflag = 0; const char* carg = NULL; int mflag = 0; const char* marg = NULL; int sflag = 0; const char* sarg = NULL; int eflag = 0; const char* earg = NULL; while ((optch = getopt(argc, argv, "c:m:s:e:h")) != -1) { switch (optch) { case 'c': cflag = 1; carg = optarg; break; case 'm': mflag = 1; marg = optarg; break; case 's': sflag = 1; sarg = optarg; break; case 'e': eflag = 1; earg = optarg; break; case 'h': default: return usage(*argv); } } size_t chunk = cflag? strtoull(carg, NULL, 10) : CHUNK_DEFAULT; float mul = mflag? strtof(marg, NULL) : 1.0f; size_t start = sflag? strtoull(sarg, NULL, 10) : 0; size_t end = eflag? strtoull(earg, NULL, 10) : chunk; float* buffer = aligned_alloc(0x40, chunk * sizeof(float)); size_t rd; if (buffer == NULL) err(1, "malloc()"); while ((rd = fread(buffer, sizeof(float), chunk, stdin))) { float min = buffer[start]; float max = buffer[start]; for (size_t i = start; i < MIN(rd, end); ++i) { min = MIN(min, buffer[i]); max = MAX(max, buffer[i]); } for (size_t i = start; i < MIN(rd, end); ++i) { buffer[i] = mul * (buffer[i] - min) / (max - min); } fwrite(buffer, sizeof(float), rd, stdout); } return 0; }