mirror of https://github.com/ecmwf/eccodes.git
grib2ppm changes: produce 16 bit images instead of 8 bit, extend size of colour map. Add capping of grey scale and speedup
This commit is contained in:
parent
809519d7dd
commit
48c22c6a8e
315
tools/grib2ppm.c
315
tools/grib2ppm.c
|
@ -8,79 +8,258 @@
|
|||
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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; i<count;++i)
|
||||
{
|
||||
if(values[i]>max)
|
||||
max = values[i];
|
||||
if(values[i]<min)
|
||||
min = values[i];
|
||||
}
|
||||
|
||||
/* PPM header */
|
||||
printf("P5\n%ld %ld\n65535\n",width,height);
|
||||
for (i=0; i<count;++i)
|
||||
{
|
||||
unsigned long c = (values[i] - min)*65535 / (max - min);
|
||||
unsigned char h = c >> 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue