From 48c22c6a8e4a02306fcc59eb72c705fe701136a1 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 13 Feb 2014 16:52:10 +0000 Subject: [PATCH] grib2ppm changes: produce 16 bit images instead of 8 bit, extend size of colour map. Add capping of grey scale and speedup --- tools/grib2ppm.c | 315 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 247 insertions(+), 68 deletions(-) diff --git a/tools/grib2ppm.c b/tools/grib2ppm.c index ed5515e46..74f93e871 100644 --- a/tools/grib2ppm.c +++ b/tools/grib2ppm.c @@ -8,79 +8,258 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -#include -#include - #include "grib_api.h" +#define CMAP_MAX 20480 + +typedef struct map +{ + double min; + double max; + unsigned char r, g, b; +} map; + +map cmap[CMAP_MAX]; +unsigned long last[CMAP_MAX] = {0,}; + +/* +unsigned char unused(char c) +{ + if (c >= 'A' && c <= 'Z') + { + return c - 'A' + 10; + } + if (c >= 'a' && c <= 'z') + { + return c - 'a' + 10; + } + return c - '0'; +} +*/ + +int next(FILE *f, char *buf) +{ + int c; + int i = 0; + while ((c = fgetc(f)) != EOF) + { + if (c == ' ' || c == '\n') + { + if (i) + { + break; + } + i++; + } + else + { + buf[i++] = c; + } + } + buf[i] = 0; + return i; +} + int main(int argc, char *argv[]) { - grib_handle* h = NULL; - FILE* f = NULL; - int i = 0; - int err = 0; - char *mode = "file"; + grib_handle *h = NULL; + FILE *f = NULL; + int i = 0; + int err = 0; + int centred = 0; + unsigned r, g, b; + int cmap_entries = 0; + double min, max; + int j; + char buf[1024]; + double lcap = -1e+100, ucap = 1e+100; - for(i = 1; i < argc; i++) - { - - if(argv[i][0] == '-') + for (i = 1; i < argc; i++) { - mode = argv[i]+1; - continue; + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + + case 'c': + centred = 1; + break; + + case 'u': + ucap = atof(argv[i + 1]); + i++; + break; + + case 'l': + lcap = atof(argv[i + 1]); + i++; + break; + + case 'm': + f = fopen(argv[i + 1], "r"); + if (!f) + { + perror(argv[i + 1]); + exit(1); + } + while (next(f, buf)) + { + min = atof(buf); + next(f, buf); + max = atof(buf); + next(f, buf); + r = atol(buf); + next(f, buf); + g = atol(buf); next(f, buf); + b = atol(buf); + + if (cmap_entries >= CMAP_MAX) + { + fprintf(stderr, "%s\n", "colour map is too large"); + exit(1); + } + cmap[cmap_entries].min = min; + cmap[cmap_entries].max = max; + cmap[cmap_entries].r = r; + cmap[cmap_entries].g = g; + cmap[cmap_entries].b = b; + cmap_entries++; + } + fclose(f); + i++; + fprintf(stderr, "Number of colours: %d\n", cmap_entries); + } + continue; + } + + f = fopen(argv[i], "r"); + if (!f) + { + perror(argv[i]); + exit(1); + } + + while ((h = grib_handle_new_from_file(0, f, &err)) != NULL) + { + long width; + long height; + double max, min; + double *values = NULL; + unsigned long *indices; + size_t count; + + GRIB_CHECK(grib_get_size(h, "values", &count), 0); + values = (double *)malloc(sizeof(double) * count); + indices = (unsigned long *)malloc(sizeof(unsigned long) * count); + + GRIB_CHECK(grib_get_long(h, "Ni", &width), 0); + GRIB_CHECK(grib_get_long(h, "Nj", &height), 0); + GRIB_CHECK(grib_get_double_array(h, "values", values, &count), 0); + + max = values[0]; + min = values[0]; + indices[0] = 0; + for (i = 1; i < count; ++i) + { + if (values[i] > max) + max = values[i]; + if (values[i] < min) + min = values[i]; + indices[i] = i; + } + + if (max > ucap) + { + max = ucap; + } + + if (min < lcap) + { + min = lcap; + } + + + fprintf(stderr, "width=%ld, height=%ld, min=%g, max=%g\n", width, height, min, max); + if (centred) + { + /* assume first column in Greenwich meridian + assume scanning mode + */ + int k = 0, j; + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + int m = (i + width / 2) % width + j * width; + indices[k++] = m; + } + } + } + + if (cmap_entries) + { + printf("P6\n%ld %ld\n255\n", width, height); + for (i = 0; i < count; ++i) + { + double v = values[indices[i]]; + unsigned int p = ((unsigned long)v) % CMAP_MAX; /* kind of hashing */ + unsigned int k = last[p]; + for (j = 0; j < cmap_entries; j++) + { + int m = (k + j) % cmap_entries; + if (v >= cmap[m].min && v < cmap[m].max) + { + last[p] = m; + printf("%c", cmap[m].r); + printf("%c", cmap[m].g); + printf("%c", cmap[m].b); + break; + } + } + if (j == cmap_entries) + { + fprintf(stderr, "Cannot find colour for %g\n", v); + exit(1); + } + + } + } + else + { + /* PPM header */ + printf("P5\n%ld %ld\n65535\n", width, height); + for (i = 0; i < count; ++i) + { + unsigned long c; + unsigned char h, l; + double v = values[indices[i]]; + if (v < lcap) + { + v = lcap; + } + if (v > ucap) + { + v = ucap; + } + c = ( v - min) * 65535 / (max - min); + h = c >> 8; + l = c & 0xff; + printf("%c", h); + printf("%c", l); + } + } + + grib_handle_delete(h); + free(values); + free(indices); + break; + } + fclose(f); + if (err) + { + fprintf(stderr, "%s\n", grib_get_error_message(err)); + exit(1); + } } - - f = fopen(argv[i],"r"); - if(!f) { - perror(argv[i]); - exit(1); - } - - while((h = grib_handle_new_from_file(0,f,&err)) != NULL) - { - long width; - long height; - double max, min; - double *values = NULL; - size_t count; - int i; - - GRIB_CHECK(grib_get_size(h,"values",&count),0); - values = (double *)malloc(sizeof(double)*count); - - GRIB_CHECK(grib_get_long(h,"Ni",&width),0); - GRIB_CHECK(grib_get_long(h,"Nj",&height),0); - GRIB_CHECK(grib_get_double_array(h,"values",values,&count),0); - - max=values[0]; - min=values[0]; - for (i=1; imax) - max = values[i]; - if(values[i]> 8; - unsigned char l = c & 0xff; - printf("%c",h); - printf("%c",l); - } - - grib_handle_delete(h); - } - fclose(f); - if(err) - { - fprintf(stderr,"%s\n",grib_get_error_message(err)); - exit(1); - } - } - return 0; + return 0; }