#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "bufrlib.h"
#include "apisample.h"
#include "bufr_io.h"
static void create_source_msg (dd* descs, int* nd, varfl** vals,
radar_data_t* d);
static int our_callback (varfl val, int ind);
static void create_sample_data (radar_data_t* d);
radar_data_t our_data;
char *version = "apisample V3.0, 5-Dec-2007\n";
void bufr_encoding_sample (radar_data_t* src_data, bufr_t* bufr_msg) {
sect_1_t s1;
dd descs[MAX_DESCS];
int nd = 0;
varfl* vals = NULL;
int ok;
long year, mon, day, hour, min;
memset (&s1, 0, sizeof (sect_1_t));
create_source_msg (descs, &nd, &vals, src_data);
s1.year = 999;
s1.mon = 999;
s1.day = 999;
s1.hour = 999;
s1.min = 999;
s1.mtab = 0;
s1.subcent = 255;
s1.gencent = 255;
s1.updsequ = 0;
s1.opsec = 0;
s1.dcat = 6;
s1.dcatst = 0;
s1.vmtab = 11;
s1.vltab = 4;
ok = (read_tables (NULL, s1.vmtab, s1.vltab, s1.subcent, s1.gencent) >= 0);
if (ok) ok = bufr_encode_sections34 (descs, nd, vals, bufr_msg);
if (ok && s1.year == 999) {
bufr_get_date_time (&year, &mon, &day, &hour, &min);
s1.year = (int) year;
s1.mon = (int) mon;
s1.day = (int) day;
s1.hour = (int) hour;
s1.min = (int) min;
s1.sec = 0;
}
if (ok) ok = bufr_encode_sections0125 (&s1, bufr_msg);
if (ok) ok = bufr_write_file (bufr_msg, "apisample.bfr");
if (vals != NULL)
free (vals);
free_descs ();
if (!ok) exit (EXIT_FAILURE);
}
void bufr_decoding_sample (bufr_t* msg, radar_data_t* data) {
sect_1_t s1;
int ok, desch, ndescs;
dd* dds = NULL;
memset (&s1, 0, sizeof (sect_1_t));
ok = bufr_decode_sections01 (&s1, msg);
bufr_sect_1_to_file (&s1, "section.1.out");
if (ok) ok = (read_tables (NULL, s1.vmtab, s1.vltab, s1.subcent,
s1.gencent) >= 0);
desch = bufr_open_descsec_r(msg);
ok = (desch >= 0);
if (ok) ok = (bufr_open_datasect_r(msg) >= 0);
ndescs = bufr_get_ndescs (msg);
if (ok) ok = bufr_in_descsec (&dds, ndescs, desch);
if (ok) ok = bufr_parse_out (dds, 0, ndescs - 1, our_callback, 1);
data = &our_data;
if (dds != (dd*) NULL)
free (dds);
bufr_close_descsec_r (desch);
bufr_close_datasect_r ();
if (ok) ok = bufr_data_to_file ("apisample.src", "apisample.img", msg);
bufr_free_data (msg);
free_descs();
exit (EXIT_SUCCESS);
}
int main (int argc, char* argv[]) {
bufr_t bufr_msg ;
memset (&bufr_msg, 0, sizeof (bufr_t));
memset (&our_data, 0, sizeof (radar_data_t));
while (argc > 1 && *argv[1] == '-')
{
if (*(argv[1] + 1) == 'v')
fprintf (stderr, "%s", version);
}
create_sample_data (&our_data);
bufr_encoding_sample (&our_data, &bufr_msg);
memset (&our_data, 0, sizeof (radar_data_t));
bufr_decoding_sample (&bufr_msg, &our_data);
bufr_free_data (&bufr_msg);
free (our_data.img.data);
exit (EXIT_SUCCESS);
}
#define fill_desc(ff,xx,yy) {\
dd.f=ff; dd.x=xx; dd.y=yy; \
bufr_desc_to_array (descs, dd, nd);}
#define fill_v(val) bufr_val_to_array (vals, val, &nv);
static void create_source_msg (dd* descs, int* nd, varfl** vals,
radar_data_t* d) {
dd dd;
int nv = 0, i;
fill_desc(3,1,1);
fill_v(d->wmoblock);
fill_v(d->wmostat);
fill_desc(3,1,192);
fill_v(d->meta.year);
fill_v(d->meta.month);
fill_v(d->meta.day);
fill_v(d->meta.hour);
fill_v(d->meta.min);
fill_v(d->img.nw.lat);
fill_v(d->img.nw.lon);
fill_v(d->img.ne.lat);
fill_v(d->img.ne.lon);
fill_v(d->img.se.lat);
fill_v(d->img.se.lon);
fill_v(d->img.sw.lat);
fill_v(d->img.sw.lon);
fill_v(d->proj.type);
fill_v(d->meta.radar.lat);
fill_v(d->meta.radar.lon);
fill_v(d->img.psizex);
fill_v(d->img.psizey);
fill_v(d->img.nrows);
fill_v(d->img.ncols);
fill_desc(3,1,22);
fill_v(d->meta.radar.lat);
fill_v(d->meta.radar.lon);
fill_v(d->meta.radar_height);
fill_desc(0,29,199);
fill_v(d->proj.majax);
fill_desc(0,29,200);
fill_v(d->proj.minax);
fill_desc(0,29,193);
fill_v(d->proj.orig.lon);
fill_desc(0,29,194);
fill_v(d->proj.orig.lat);
fill_desc(0,29,195);
fill_v(d->proj.xoff);
fill_desc(0,29,196);
fill_v(d->proj.yoff);
fill_desc(0,29,197);
fill_v(d->proj.stdpar1);
fill_desc(0,29,198);
fill_v(d->proj.stdpar2);
fill_desc(0,30,31);
fill_v(d->img.type);
fill_desc(0,29,2);
fill_v(d->img.grid);
fill_desc(0,33,3);
fill_v(d->img.qual);
fill_desc(2,1,129);
fill_desc(3,13,9);
fill_v(d->img.scale.vals[0]);
fill_v(d->img.scale.nvals -1);
for (i = 1; i < d->img.scale.nvals; i++) {
fill_v(d->img.scale.vals[i]);
}
fill_desc(2,1,0);
fill_desc(0,21,198);
fill_v(d->img.scale.offset);
fill_desc(0,21,199);
fill_v(d->img.scale.increment);
fill_desc(3,21,193);
rlenc_from_mem (d->img.data, d->img.nrows, d->img.ncols, vals, &nv);
free(d->img.data);
}
static int our_callback (varfl val, int ind) {
radar_data_t* b = &our_data;
bufrval_t* v;
varfl* vv;
int i = 0, nv, nr, nc;
dd* d;
if (ind == _desc_special) return 1;
if (des[ind]->id == SEQDESC) {
d = &(des[ind]->seq->d);
v = bufr_open_val_array ();
if (v == (bufrval_t*) NULL) return 0;
if (bufr_check_fxy (d, 3,1,1)) {
bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
bufr_val_to_global, 0);
b->wmoblock = (int) v->vals[i++];
b->wmostat = (int) v->vals[i];
}
else if (bufr_check_fxy (d, 3,1,192)) {
bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
bufr_val_to_global, 0);
vv = v->vals;
i = 0;
b->meta.year = (int) vv[i++];
b->meta.month = (int) vv[i++];
b->meta.day = (int) vv[i++];
b->meta.hour = (int) vv[i++];
b->meta.min = (int) vv[i++];
b->img.nw.lat = vv[i++];
b->img.nw.lon = vv[i++];
b->img.ne.lat = vv[i++];
b->img.ne.lon = vv[i++];
b->img.se.lat = vv[i++];
b->img.se.lon = vv[i++];
b->img.sw.lat = vv[i++];
b->img.sw.lon = vv[i++];
b->proj.type = (int) vv[i++];
b->meta.radar.lat = vv[i++];
b->meta.radar.lon = vv[i++];
b->img.psizex = vv[i++];
b->img.psizey = vv[i++];
b->img.nrows = (int) vv[i++];
b->img.ncols = (int) vv[i++];
}
else if (bufr_check_fxy (d, 3,1,22)) {
bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
bufr_val_to_global, 0);
vv = v->vals;
i = 0;
b->meta.radar.lat = vv[i++];
b->meta.radar.lon = vv[i++];
b->meta.radar_height = vv[i];
}
else if (bufr_check_fxy (d, 3,13,9)) {
int j;
bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
bufr_val_to_global, 0);
vv = v->vals;
i = 0;
b->img.scale.vals[0] = vv[i++];
b->img.scale.nvals = (int) vv[i++] + 1;
assert(b->img.scale.nvals < 256);
for (j = 1; j < b->img.scale.nvals; j++) {
b->img.scale.vals[j] = vv[i++];
}
}
else if (bufr_check_fxy (d, 3,21,193)) {
if (!bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
bufr_val_to_global, 0)) {
bufr_close_val_array ();
return 0;
}
if (!rldec_to_mem (v->vals, &(b->img.data), &nv, &nr, &nc)) {
bufr_close_val_array ();
fprintf (stderr, "Error during runlength-compression.\n");
return 0;
}
}
else {
fprintf (stderr,
"Unknown sequence descriptor %d %d %d", d->f, d->x, d->y);
}
bufr_close_val_array ();
}
else if (des[ind]->id == ELDESC) {
d = &(des[ind]->el->d);
if (bufr_check_fxy (d, 0,29,199))
b->proj.majax = val;
else if (bufr_check_fxy (d, 0,29,200))
b->proj.minax = val;
else if (bufr_check_fxy (d, 0,29,193))
b->proj.orig.lon = val;
else if (bufr_check_fxy (d, 0,29,194))
b->proj.orig.lat = val;
else if (bufr_check_fxy (d, 0,29,195))
b->proj.xoff = (int) val;
else if (bufr_check_fxy (d, 0,29,196))
b->proj.yoff = (int) val;
else if (bufr_check_fxy (d, 0,29,197))
b->proj.stdpar1 = val;
else if (bufr_check_fxy (d, 0,29,198))
b->proj.stdpar2 = val;
else if (bufr_check_fxy (d, 0,30,31))
b->img.type = (int) val;
else if (bufr_check_fxy (d, 0,29,2))
b->img.grid = (int) val;
else if (bufr_check_fxy (d, 0,33,3))
b->img.qual = val;
else if (bufr_check_fxy (d, 0,21,198))
b->img.scale.offset = val;
else if (bufr_check_fxy (d, 0,21,199))
b->img.scale.increment = val;
else {
fprintf (stderr,
"Unknown element descriptor %d %d %d", d->f, d->x, d->y);
return 0;
}
}
return 1;
}
#define NROWS 200
#define NCOLS 200
static void create_sample_data (radar_data_t* d) {
int i;
d->img.data = (unsigned short*) calloc (NROWS * NCOLS,
sizeof (unsigned short));
if (d->img.data == NULL) {
fprintf (stderr, "Could not allocate memory for sample image!\n");
exit (EXIT_FAILURE);
}
#ifdef VERBOSE
fprintf (stderr, "RAND_MAX = %d\n", RAND_MAX);
#endif
for (i = 0; i < NROWS * NCOLS; i++) {
d->img.data[i] = (unsigned short) ((float) rand() / RAND_MAX * 254);
#ifdef VERBOSE
fprintf (stderr, "Value: %d\n", d->img.data[i]);
#endif
}
d->wmoblock = 11;
d->wmostat = 164;
d->meta.year = 2007;
d->meta.month = 12;
d->meta.day = 5;
d->meta.hour = 12;
d->meta.min = 5;
d->meta.radar.lat = 47.06022;
d->meta.radar.lon = 15.45772;
d->meta.radar_height = 355;
d->img.nw.lat = 50.4371;
d->img.nw.lon = 8.1938;
d->img.ne.lat = 50.3750;
d->img.ne.lon = 19.7773;
d->img.se.lat = 44.5910;
d->img.se.lon = 19.1030;
d->img.sw.lat = 44.6466;
d->img.sw.lon = 8.7324;
d->img.psizex = 1000;
d->img.psizey = 1000;
d->img.nrows = NROWS;
d->img.ncols = NCOLS;
d->img.type = 2;
d->img.grid = 0;
d->img.qual = MISSVAL;
d->img.scale.nvals = 255;
for (i = 0; i < 255; i++) {
d->img.scale.vals[i] = i * 0.5 - 31.0;
}
d->img.scale.offset = -31;
d->img.scale.increment = 0.5;
d->proj.type = 2;
d->proj.majax = 6378137;
d->proj.minax = 6356752;
d->proj.orig.lon = 13.333333;
d->proj.orig.lat = 47.0;
d->proj.xoff = 458745;
d->proj.yoff = 364548;
d->proj.stdpar1 = 46.0;
d->proj.stdpar2 = 49.0;
}