39#define __STDC_LIMIT_MACROS
56#include <jasper/jasper.h>
59const double GRIB_MISSING_VALUE = GRIB_NOTDEF;
74 stat_proc.t =
nullptr;
91 earth_sphere_scale_factor;
92 int earth_sphere_scale_value;
94 unsigned char earth_major_scale_factor;
96 int earth_major_scale_value;
99 unsigned char earth_minor_scale_factor;
101 int earth_minor_scale_value;
105 double slat, slon, latin1, latin2, splat, splon;
123 int rescomp, scan_mode, proj_flag;
125 int param_cat, param_num, gen_proc, time_unit, fcst_time;
126 int ens_type, perturb_num, derived_fcst_code, nfcst_in_ensemble;
127 int lvl1_type, lvl2_type;
130 int eyr, emo, edy, etime;
131 int num_ranges, nmiss;
135 int stat_proc, type, num_points;
138 int split_method, miss_val_mgmt;
139 unsigned int num_groups;
140 float primary_miss_sub, secondary_miss_sub;
145 unsigned int ref, incr, last, pack_width;
148 unsigned int order, order_vals_width;
152 int flags, block_size, rsi;
157 int E, D, num_packed, pack_width, orig_val_type;
159 unsigned char *bitmap;
177 unsigned char *buffer;
179 int total_len, disc, ed_num;
180 int center_id, sub_center_id, table_ver, local_table_ver, ref_time_type;
181 int yr, mo, dy, time;
182 int prod_status, data_type;
189static int dec_jpeg2000(
char *injpc,
int bufsize,
int *outfld)
233 jas_image_t *image =
nullptr;
234 jas_stream_t *jpcstream;
235 jas_image_cmpt_t *pcmpt;
236 char *opts =
nullptr;
246 jpcstream = jas_stream_memopen(injpc, bufsize);
247 if (jpcstream ==
nullptr) {
248 printf(
" dec_jpeg2000: no memory\n");
254 image = jpc_decode(jpcstream, opts);
255 if (image ==
nullptr) {
256 printf(
" jpc_decode return = %d \n", ier);
260 pcmpt = image->cmpts_[0];
265 if (image->numcmpts_ != 1) {
266 printf(
"dec_jpeg2000: Found color image. Grayscale expected.\n");
274 data = jas_matrix_create(jas_image_height(image), jas_image_width(image));
275 jas_image_readcmpt(image, 0, 0, 0, jas_image_width(image),
276 jas_image_height(image), data);
281 for (i = 0; i < pcmpt->height_; i++)
282 for (j = 0; j < pcmpt->width_; j++) outfld[k++] = data->rows_[i][j];
286 jas_matrix_destroy(data);
287 ier = jas_stream_close(jpcstream);
288 jas_image_destroy(image);
294static unsigned int uint2(
unsigned char const *p) {
return (p[0] << 8) + p[1]; }
296static unsigned int uint4(
unsigned const char *p) {
297 return ((p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]);
300static int int2(
unsigned const char *p) {
303 i = -(((p[0] & 0x7f) << 8) + p[1]);
305 i = (p[0] << 8) + p[1];
310static int int4(
unsigned const char *p) {
313 i = -(((p[0] & 0x7f) << 24) + (p[1] << 16) + (p[2] << 8) + p[3]);
315 i = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
320static float ieee2flt(
unsigned const char *ieee) {
324 if ((ieee[0] & 127) == 0 && ieee[1] == 0 && ieee[2] == 0 && ieee[3] == 0)
327 exp = ((ieee[0] & 127) << 1) + (ieee[1] >> 7);
328 fmant = (double)((
int)ieee[3] + (int)(ieee[2] << 8) +
329 (int)((ieee[1] | 128) << 16));
330 if (ieee[0] & 128) fmant = -fmant;
332 return (
float)(ldexp(fmant, (
int)(exp - 128 - 22)));
335static inline void getBits(
unsigned const char *buf,
int *loc,
size_t first,
343 zuint oct = first / 8;
344 zuint bit = first % 8;
346 zuint val = (buf[oct] << 24) + (buf[oct + 1] << 16) + (buf[oct + 2] << 8) +
349 val = val >> (32 - nbBits);
359 size_t ofs = grib_msg->offset / 8;
360 unsigned char *b = grib_msg->buffer + ofs;
364 grib_msg->center_id = uint2(b + 5);
365 grib_msg->sub_center_id = uint2(b + 7);
366 grib_msg->table_ver = b[9];
367 grib_msg->local_table_ver = b[10];
368 grib_msg->ref_time_type = b[11];
369 grib_msg->yr = uint2(b + 12);
370 grib_msg->mo = b[14];
371 grib_msg->dy = b[15];
375 grib_msg->time = hh * 10000 + mm * 100 + ss;
376 grib_msg->prod_status = b[19];
377 grib_msg->data_type = b[20];
378 grib_msg->offset += length * 8;
381static bool unpackLUS(
GRIBMessage *grib_msg) {
return true; }
384 size_t ofs = grib_msg->offset / 8;
385 unsigned char *b = grib_msg->buffer + ofs;
387 grib_msg->md.earth_shape = b[14];
389 grib_msg->md.earth_sphere_scale_factor =
391 grib_msg->md.earth_sphere_scale_value =
394 grib_msg->md.earth_major_scale_factor =
396 grib_msg->md.earth_major_scale_value =
399 grib_msg->md.earth_minor_scale_factor =
401 grib_msg->md.earth_minor_scale_value =
406 int src, num_in_list;
407 size_t ofs = grib_msg->offset / 8;
408 unsigned char *b = grib_msg->buffer + ofs;
412 fprintf(stderr,
"Don't recognize predetermined grid definitions");
417 if (num_in_list > 0) {
418 fprintf(stderr,
"Unable to unpack quasi-regular grids");
423 grib_msg->md.gds_templ_num = uint2(b + 12);
424 switch (grib_msg->md.gds_templ_num) {
428 parse_earth(grib_msg);
430 grib_msg->md.nx = uint4(b + 30);
431 grib_msg->md.ny = uint4(b + 34);
434 int4(b + 46) / 1000000.;
436 int4(b + 50) / 1000000.;
438 grib_msg->md.rescomp = b[54];
440 grib_msg->md.lats.elat =
441 int4(b + 55) / 1000000.;
442 grib_msg->md.lons.elon =
443 int4(b + 59) / 1000000.;
445 grib_msg->md.xinc.loinc =
446 uint4(b + 63) / 1000000.;
448 if (grib_msg->md.gds_templ_num == 0)
449 grib_msg->md.yinc.lainc =
450 uint4(b + 67) / 1000000.;
452 grib_msg->md.scan_mode = b[71];
455 parse_earth(grib_msg);
457 grib_msg->md.nx = uint4(b + 30);
458 grib_msg->md.ny = uint4(b + 34);
461 int4(b + 38) / 1000000.;
463 int4(b + 42) / 1000000.;
465 grib_msg->md.rescomp = b[46];
471 grib_msg->md.lats.elat =
472 int4(b + 51) / 1000000.;
473 grib_msg->md.lons.elon =
474 int4(b + 55) / 1000000.;
476 grib_msg->md.scan_mode = b[59];
478 grib_msg->md.xinc.loinc = uint4(b + 64) / 1000.;
479 grib_msg->md.yinc.lainc = uint4(b + 68) / 1000.;
482 parse_earth(grib_msg);
484 grib_msg->md.nx = uint4(b + 30);
485 grib_msg->md.ny = uint4(b + 34);
488 int4(b + 38) / 1000000.;
490 int4(b + 42) / 1000000.;
492 grib_msg->md.rescomp = b[46];
494 grib_msg->md.lats.lad = int4(b + 47) / 1000000.;
495 grib_msg->md.lons.lov = int4(b + 51) / 1000000.;
497 grib_msg->md.xinc.dxinc =
498 int4(b + 55) / 1000.;
499 grib_msg->md.yinc.dyinc =
500 int4(b + 59) / 1000.;
502 grib_msg->md.proj_flag = b[63];
503 grib_msg->md.scan_mode = b[64];
505 grib_msg->md.latin1 = int4(b + 65) / 1000000.;
506 grib_msg->md.latin2 = int4(b + 69) / 1000000.;
509 int4(b + 73) / 1000000.;
515 fprintf(stderr,
"Grid template %d is not understood\n",
516 grib_msg->md.gds_templ_num);
522static void unpack_stat_proc(
GRIBMessage *grib_msg,
unsigned const char *b) {
526 grib_msg->md.stat_proc.eyr = uint2(b);
527 grib_msg->md.stat_proc.emo = b[2];
528 grib_msg->md.stat_proc.edy = b[3];
532 grib_msg->md.stat_proc.etime = hh * 10000 + mm * 100 + ss;
534 grib_msg->md.stat_proc.num_ranges =
536 grib_msg->md.stat_proc.nmiss =
539 if (grib_msg->md.stat_proc.t != 0) {
540 delete[] grib_msg->md.stat_proc.t;
542 grib_msg->md.stat_proc.t =
545 for (n = 0; n < (size_t)grib_msg->md.stat_proc.num_ranges; n++) {
546 grib_msg->md.stat_proc.t[n].proc_code = b[off];
547 grib_msg->md.stat_proc.t[n].incr_type = b[off + 1];
548 grib_msg->md.stat_proc.t[n].time_unit = b[off + 2];
549 grib_msg->md.stat_proc.t[n].time_length = uint4(b + off + 3);
550 grib_msg->md.stat_proc.t[n].incr_unit = b[off + 7];
551 grib_msg->md.stat_proc.t[n].incr_length = uint4(b + off + 8);
558 int num_coords, factor;
559 size_t ofs = grib_msg->offset / 8;
560 unsigned char *b = grib_msg->buffer + ofs;
562 num_coords = uint2(b + 5);
563 if (num_coords > 0) {
564 fprintf(stderr,
"Unable to decode hybrid coordinates");
568 grib_msg->md.pds_templ_num =
570 grib_msg->md.stat_proc.num_ranges = 0;
571 switch (grib_msg->md.pds_templ_num) {
579 grib_msg->md.ens_type = -1;
580 grib_msg->md.derived_fcst_code = -1;
581 grib_msg->md.spatial_proc.type = -1;
582 grib_msg->md.param_cat = b[9];
583 grib_msg->md.param_num = b[10];
584 grib_msg->md.gen_proc = b[11];
586 grib_msg->md.time_unit = b[17];
587 grib_msg->md.fcst_time = uint4(b + 18);
589 grib_msg->md.lvl1_type = b[22];
591 grib_msg->md.lvl1 = int4(b + 24) / pow(10., (
double)factor);
593 grib_msg->md.lvl2_type = b[28];
595 grib_msg->md.lvl2 = int4(b + 30) / pow(10., (
double)factor);
597 switch (grib_msg->md.pds_templ_num) {
600 grib_msg->md.ens_type = b[34];
601 grib_msg->md.perturb_num = b[35];
602 grib_msg->md.nfcst_in_ensemble = b[36];
604 switch (grib_msg->md.pds_templ_num) {
606 unpack_stat_proc(grib_msg, b + 37);
612 grib_msg->md.derived_fcst_code = b[34];
613 grib_msg->md.nfcst_in_ensemble = b[35];
615 switch (grib_msg->md.pds_templ_num) {
617 unpack_stat_proc(grib_msg, b + 36);
622 unpack_stat_proc(grib_msg, b + 34);
625 grib_msg->md.spatial_proc.stat_proc = b[34];
626 grib_msg->md.spatial_proc.type = b[35];
627 grib_msg->md.spatial_proc.num_points = b[36];
632 fprintf(stderr,
"Product Definition Template %d is not understood\n",
633 grib_msg->md.pds_templ_num);
641 size_t ofs = grib_msg->offset / 8;
642 unsigned char *b = grib_msg->buffer + ofs;
644 grib_msg->md.num_packed = uint4(b + 5);
645 grib_msg->md.drs_templ_num =
648 switch (grib_msg->md.drs_templ_num) {
650 grib_msg->md.precision = b[11];
663 grib_msg->md.R = ieee2flt(b + 11);
664 grib_msg->md.E = int2(b + 15);
665 grib_msg->md.D = int2(b + 17);
666 grib_msg->md.R /= pow(10., grib_msg->md.D);
668 grib_msg->md.pack_width = b[19];
669 grib_msg->md.orig_val_type = b[20];
671 if (grib_msg->md.drs_templ_num == 3 || grib_msg->md.drs_templ_num == 2) {
672 grib_msg->md.complex_pack.split_method = b[21];
673 grib_msg->md.complex_pack.miss_val_mgmt = b[22];
674 if (grib_msg->md.orig_val_type == 0) {
675 grib_msg->md.complex_pack.primary_miss_sub = ieee2flt(b + 23);
676 grib_msg->md.complex_pack.secondary_miss_sub = ieee2flt(b + 27);
677 }
else if (grib_msg->md.orig_val_type == 1) {
678 grib_msg->md.complex_pack.primary_miss_sub = uint4(b + 23);
679 grib_msg->md.complex_pack.secondary_miss_sub = uint4(b + 27);
682 "Unable to decode missing value substitutes for original "
684 grib_msg->md.orig_val_type);
687 grib_msg->md.complex_pack.num_groups = uint4(b + 31);
689 grib_msg->md.complex_pack.width.ref = b[35];
690 grib_msg->md.complex_pack.width.pack_width = b[36];
692 grib_msg->md.complex_pack.length.ref = uint4(b + 37);
693 grib_msg->md.complex_pack.length.incr = b[41];
694 grib_msg->md.complex_pack.length.last = uint4(b + 42);
695 grib_msg->md.complex_pack.length.pack_width = b[46];
697 if (grib_msg->md.drs_templ_num == 42) {
698 grib_msg->md.ccsds.flags = b[21];
699 grib_msg->md.ccsds.block_size = b[22];
700 grib_msg->md.ccsds.rsi = uint2(b + 23);
702 if (grib_msg->md.drs_templ_num == 3) {
703 grib_msg->md.complex_pack.spatial_diff.order = b[47];
704 grib_msg->md.complex_pack.spatial_diff.order_vals_width = b[48];
706 grib_msg->md.complex_pack.spatial_diff.order = 0;
707 grib_msg->md.complex_pack.spatial_diff.order_vals_width = 0;
711 fprintf(stderr,
"Data template %d is not understood\n",
712 grib_msg->md.drs_templ_num);
720 int ind, len, n, bit;
721 size_t ofs = grib_msg->offset / 8;
722 unsigned char *b = grib_msg->buffer + ofs;
729 if (len < 7)
return false;
731 grib_msg->md.bmssize = len;
733 delete[] grib_msg->md.bitmap;
734 delete[] grib_msg->md.bms;
735 grib_msg->md.bitmap =
new unsigned char[len];
736 grib_msg->md.bms =
new zuchar[grib_msg->md.bmssize];
737 memcpy(grib_msg->md.bms, b + 6, grib_msg->md.bmssize);
738 for (n = 0; n < len; n++) {
739 getBits(grib_msg->buffer, &bit, grib_msg->offset + 48 + n, 1);
740 grib_msg->md.bitmap[n] = bit;
747 delete[] grib_msg->md.bitmap;
748 grib_msg->md.bitmap =
nullptr;
749 delete[] grib_msg->md.bms;
750 grib_msg->md.bms =
nullptr;
751 grib_msg->md.bmssize = 0;
755 "This code is not currently set up to deal with predefined "
768 int *ref_vals, *widths;
770 int *first_vals = 0, sign, omin;
771 long long miss_val, group_miss_val;
774 float lastgp, D = pow(10., grib_msg->md.D), E = pow(2., grib_msg->md.E);
777 groups.first_vals =
nullptr;
779 off = grib_msg->offset + 40;
780 int npoints = grib_msg->md.ny * grib_msg->md.nx;
781 switch (grib_msg->md.drs_templ_num) {
783 grib_msg->grids.gridpoints =
new double[npoints];
784 for (l = 0; l < npoints; l++) {
785 if (grib_msg->md.bitmap ==
nullptr || grib_msg->md.bitmap[l] == 1) {
786 getBits(grib_msg->buffer, &pval, off, grib_msg->md.pack_width);
787 grib_msg->grids.gridpoints[l] = grib_msg->md.R + pval * E / D;
788 off += grib_msg->md.pack_width;
790 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
794 if (grib_msg->md.complex_pack.num_groups > 0) {
795 if (grib_msg->md.complex_pack.spatial_diff.order) {
797 new int[grib_msg->md.complex_pack.spatial_diff.order];
798 for (n = 0; n < grib_msg->md.complex_pack.spatial_diff.order; ++n) {
800 grib_msg->buffer, &groups.first_vals[n], off,
801 grib_msg->md.complex_pack.spatial_diff.order_vals_width * 8);
802 off += grib_msg->md.complex_pack.spatial_diff.order_vals_width * 8;
805 getBits(grib_msg->buffer, &groups.sign, off, 1);
807 grib_msg->buffer, &groups.omin, off + 1,
808 grib_msg->md.complex_pack.spatial_diff.order_vals_width * 8 - 1);
809 if (groups.sign == 1) {
810 groups.omin = -groups.omin;
812 off += grib_msg->md.complex_pack.spatial_diff.order_vals_width * 8;
816 grib_msg->grids.gridpoints =
new double[npoints];
817 if (grib_msg->md.complex_pack.num_groups == 0) {
818 for (l = 0; l < npoints; ++l) {
819 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
823 if (grib_msg->md.complex_pack.miss_val_mgmt > 0) {
824 groups.miss_val = pow(2., grib_msg->md.pack_width) - 1;
826 groups.miss_val = GRIB_MISSING_VALUE;
829 groups.ref_vals =
new int[grib_msg->md.complex_pack.num_groups];
830 groups.widths =
new int[grib_msg->md.complex_pack.num_groups];
831 groups.lengths =
new int[grib_msg->md.complex_pack.num_groups];
833 for (n = 0; n < grib_msg->md.complex_pack.num_groups; ++n) {
834 getBits(grib_msg->buffer, &groups.ref_vals[n], off,
835 grib_msg->md.pack_width);
836 off += grib_msg->md.pack_width;
838 off = (off + 7) & ~7;
840 for (n = 0; n < grib_msg->md.complex_pack.num_groups; ++n) {
841 getBits(grib_msg->buffer, &groups.widths[n], off,
842 grib_msg->md.complex_pack.width.pack_width);
843 groups.widths[n] += grib_msg->md.complex_pack.width.ref;
844 off += grib_msg->md.complex_pack.width.pack_width;
846 off = (off + 7) & ~7;
848 for (n = 0; n < grib_msg->md.complex_pack.num_groups; ++n) {
849 getBits(grib_msg->buffer, &groups.lengths[n], off,
850 grib_msg->md.complex_pack.length.pack_width);
851 off += grib_msg->md.complex_pack.length.pack_width;
853 off = (off + 7) & ~7;
855 groups.max_length = 0;
856 for (n = 0; n < grib_msg->md.complex_pack.num_groups - 1; ++n) {
858 grib_msg->md.complex_pack.length.ref +
859 groups.lengths[n] * grib_msg->md.complex_pack.length.incr;
860 if (groups.lengths[n] > groups.max_length) {
861 groups.max_length = groups.lengths[n];
864 groups.lengths[n] = grib_msg->md.complex_pack.length.last;
865 if (groups.lengths[n] > groups.max_length) {
866 groups.max_length = groups.lengths[n];
869 for (n = 0, l = 0; n < grib_msg->md.complex_pack.num_groups; ++n) {
870 if (groups.widths[n] > 0) {
871 if (grib_msg->md.complex_pack.miss_val_mgmt > 0) {
872 groups.group_miss_val = pow(2., groups.widths[n]) - 1;
874 groups.group_miss_val = GRIB_MISSING_VALUE;
876 for (
int i = 0; i < groups.lengths[n];) {
877 if (grib_msg->md.bitmap !=
nullptr && grib_msg->md.bitmap[l] == 0) {
878 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
880 getBits(grib_msg->buffer, &pval, off, groups.widths[n]);
881 off += groups.widths[n];
882 if (pval == groups.group_miss_val) {
883 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
885 grib_msg->grids.gridpoints[l] =
886 pval + groups.ref_vals[n] + groups.omin;
893 for (
int i = 0; i < groups.lengths[n];) {
894 if (grib_msg->md.bitmap !=
nullptr && grib_msg->md.bitmap[l] == 0) {
895 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
897 if (groups.ref_vals[n] == groups.miss_val) {
898 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
900 grib_msg->grids.gridpoints[l] =
901 groups.ref_vals[n] + groups.omin;
910 for (; l < npoints; ++l) {
911 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
914 if (grib_msg->md.drs_templ_num == 3) {
915 if (groups.first_vals !=
nullptr) {
916 for (n = grib_msg->md.complex_pack.spatial_diff.order - 1; n > 0;
918 lastgp = groups.first_vals[n] - groups.first_vals[n - 1];
919 for (l = 0, m = 0; l < grib_msg->md.nx * grib_msg->md.ny; ++l) {
920 if (grib_msg->grids.gridpoints[l] != GRIB_MISSING_VALUE) {
921 if (m >= grib_msg->md.complex_pack.spatial_diff.order) {
922 grib_msg->grids.gridpoints[l] += lastgp;
923 lastgp = grib_msg->grids.gridpoints[l];
930 for (l = 0, m = 0, lastgp = 0; l < npoints; ++l) {
931 if (grib_msg->grids.gridpoints[l] != GRIB_MISSING_VALUE) {
932 if (m < grib_msg->md.complex_pack.spatial_diff.order) {
933 grib_msg->grids.gridpoints[l] =
934 grib_msg->md.R + groups.first_vals[m] * E / D;
935 lastgp = grib_msg->md.R * D / E + groups.first_vals[m];
937 lastgp += grib_msg->grids.gridpoints[l];
938 grib_msg->grids.gridpoints[l] = lastgp * E / D;
943 delete[] groups.first_vals;
945 for (l = 0; l < npoints; ++l) {
946 if (grib_msg->grids.gridpoints[l] != GRIB_MISSING_VALUE) {
947 grib_msg->grids.gridpoints[l] =
948 grib_msg->md.R + grib_msg->grids.gridpoints[l] * E / D;
951 delete[] groups.ref_vals;
952 delete[] groups.widths;
953 delete[] groups.lengths;
957 if (grib_msg->md.precision == 1) {
958 grib_msg->grids.gridpoints =
new double[npoints];
959 for (
int ll = 0; ll < npoints; ll++) {
960 if (grib_msg->md.bitmap ==
nullptr || grib_msg->md.bitmap[ll] == 1) {
961 grib_msg->grids.gridpoints[ll] =
962 ieee2flt(grib_msg->buffer + off / 8);
965 grib_msg->grids.gridpoints[ll] = GRIB_MISSING_VALUE;
967 }
else if (grib_msg->md.precision == 2) {
968 static const int one = 1;
969 bool const is_lsb = *((
char *)&one) == 1;
970 grib_msg->grids.gridpoints =
new double[npoints];
971 for (l = 0; l < npoints; l++) {
972 if (grib_msg->md.bitmap ==
nullptr || grib_msg->md.bitmap[l] == 1) {
975 unsigned char temp[8];
976 for (
int j = 0; j < 8; j++) {
977 temp[j] = grib_msg->buffer[off / 8 + 7 - j];
981 memcpy(&d, grib_msg->buffer + off / 8, 8);
983 grib_msg->grids.gridpoints[l] = d;
986 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
990 "g2_unpack7: Invalid precision=%d for Data Section 5.4.\n",
991 grib_msg->md.precision);
997 getBits(grib_msg->buffer, &len, grib_msg->offset, 32);
998 if (len < 5)
return false;
1000 int nbits = grib_msg->md.pack_width;
1001 int flags = grib_msg->md.ccsds.flags;
1004 size_t nbytes = (nbits + 7) / 8;
1005 if (nbytes == 3 && !(flags & AEC_DATA_3BYTE)) nbytes = 4;
1006 size_t nvals = grib_msg->md.num_packed;
1007 std::vector<unsigned char> out(nvals * nbytes);
1008 if (nbits > 0 && len > 0 && nvals > 0) {
1011 strm.bits_per_sample = nbits;
1012 strm.block_size = grib_msg->md.ccsds.block_size;
1013 strm.rsi = grib_msg->md.ccsds.rsi;
1014 strm.next_in = &grib_msg->buffer[grib_msg->offset / 8 + 5];
1015 strm.avail_in = len;
1016 strm.next_out = out.data();
1017 strm.avail_out = out.size();
1018 if (aec_buffer_decode(&strm) != AEC_OK) {
1019 erreur(
"CCSDS decoding failed (%d bits)", nbits);
1023 grib_msg->grids.gridpoints =
new double[npoints];
1025 for (l = 0; l < npoints; l++) {
1026 if ((grib_msg->md.bitmap ==
nullptr || grib_msg->md.bitmap[l] == 1) &&
1028 const unsigned char *p = out.data() + cnt++ * nbytes;
1030 for (
size_t k = 0; k < nbytes; k++)
1031 v |= (
unsigned int)(flags & AEC_DATA_MSB ? p[k] : p[nbytes - 1 - k])
1032 << (8 * (nbytes - 1 - k));
1033 grib_msg->grids.gridpoints[l] = grib_msg->md.R + v * E / D;
1035 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
1041 int len, *jvals, cnt;
1042 getBits(grib_msg->buffer, &len, grib_msg->offset, 32);
1043 if (len < 5)
return false;
1045 jvals =
new int[npoints];
1046 grib_msg->grids.gridpoints =
new double[npoints];
1048 dec_jpeg2000((
char *)&grib_msg->buffer[grib_msg->offset / 8 + 5], len,
1051 for (l = 0; l < npoints; l++) {
1052 if (grib_msg->md.bitmap ==
nullptr || grib_msg->md.bitmap[l] == 1) {
1053 if (len == 0) jvals[cnt] = 0;
1054 grib_msg->grids.gridpoints[l] = grib_msg->md.R + jvals[cnt++] * E / D;
1056 grib_msg->grids.gridpoints[l] = GRIB_MISSING_VALUE;
1062 erreur(
"Unknown packing %d", grib_msg->md.drs_templ_num);
1068static zuchar GRBV2_TO_DATA(
int productDiscipline,
int dataCat,
int dataNum) {
1071 switch (productDiscipline) {
1100 ret = GRB_HUMID_SPEC;
1103 ret = GRB_HUMID_REL;
1106 ret = GRB_PRECIP_RATE;
1111 ret = GRB_PRECIP_TOT;
1114 ret = GRB_SNOW_DEPTH;
1117 ret = GRB_FRZRAIN_CATEG;
1121 ret = GRB_SNOW_CATEG;
1131 ret = GRB_WIND_SPEED;
1140 ret = GRB_WIND_GUST;
1154 ret = GRB_GEOPOT_HGT;
1165 ret = GRB_CLOUD_TOT;
1181 ret = GRB_COMP_REFL;
1192 case 3: ret= GRB_WVHGT;
break;
1193 DATA_TO_GRBV2[DATA_WAVES_WND_DIR] = grb2DataType(10,0,4);
1194 DATA_TO_GRBV2[DATA_WAVES_WND_HGT] = grb2DataType(10,0,5);
1195 DATA_TO_GRBV2[DATA_WAVES_WND_PERIOD] = grb2DataType(10,0,6);
1196 DATA_TO_GRBV2[DATA_WAVES_SWL_DIR] = grb2DataType(10,0,7);
1197 DATA_TO_GRBV2[DATA_WAVES_SWL_HGT] = grb2DataType(10,0,8);
1198 DATA_TO_GRBV2[DATA_WAVES_SWL_PERIOD] = grb2DataType(10,0,9);
1199 DATA_TO_GRBV2[DATA_WAVES_PRIM_DIR] = grb2DataType(10,0,10);
1200 DATA_TO_GRBV2[DATA_WAVES_PRIM_PERIOD] = grb2DataType(10,0,11);
1201 DATA_TO_GRBV2[DATA_WAVES_SEC_DIR] = grb2DataType(10,0,12);
1202 DATA_TO_GRBV2[DATA_WAVES_SEC_PERIOD] = grb2DataType(10,0,13);
1234 ret = GRB_CUR_SPEED;
1256 erreur(
"unknown Discipline %d dataCat %d dataNum %d", productDiscipline,
1264static int mapStatisticalEndTime(
GRIBMessage *grid) {
1268 if (grid->md.time_unit == grid->md.stat_proc.t[0].time_unit)
1269 switch (grid->md.time_unit) {
1273 return grid->md.fcst_time + grid->md.stat_proc.t[0].time_length;
1276 return (grid->md.stat_proc.edy - grid->dy);
1278 return (grid->md.stat_proc.emo - grid->mo);
1280 return (grid->md.stat_proc.eyr - grid->yr);
1282 fprintf(stderr,
"Unable to map end time with units %d to GRIB1\n",
1283 grid->md.time_unit);
1287 if (grid->md.time_unit == 0 && grid->md.stat_proc.t[0].time_unit == 1) {
1289 return grid->md.fcst_time + grid->md.stat_proc.t[0].time_length * 60;
1292 if (grid->md.time_unit == 1 && grid->md.stat_proc.t[0].time_unit == 0 &&
1293 (grid->md.stat_proc.t[0].time_unit % 60) != 0) {
1295 return grid->md.fcst_time + grid->md.stat_proc.t[0].time_length / 60;
1298 fprintf(stderr,
"Unable to map end time %d %d %d %d \n", grid->md.time_unit,
1299 grid->md.stat_proc.t[0].time_unit, grid->md.fcst_time,
1300 grid->md.stat_proc.t[0].time_length);
1305static bool mapTimeRange(
GRIBMessage *grid, zuint *p1, zuint *p2,
1306 zuchar *t_range,
int *n_avg,
int *n_missing,
1308 switch (grid->md.pds_templ_num) {
1314 *p1 = grid->md.fcst_time;
1316 *n_avg = *n_missing = 0;
1321 if (grid->md.stat_proc.num_ranges > 1) {
1322 if (center == 7 && grid->md.stat_proc.num_ranges == 2) {
1324 *p2 = grid->md.stat_proc.t[0].incr_length;
1325 *p1 = *p2 - grid->md.stat_proc.t[1].time_length;
1326 *n_avg = grid->md.stat_proc.t[0].time_length;
1327 switch (grid->md.stat_proc.t[0].proc_code) {
1376 "Unable to map NCEP statistical process code %d to GRIB1\n",
1377 grid->md.stat_proc.t[0].proc_code);
1382 "Unable to map multiple statistical processes to GRIB1\n");
1386 switch (grid->md.stat_proc.t[0].proc_code) {
1390 switch (grid->md.stat_proc.t[0].proc_code) {
1401 *p1 = grid->md.fcst_time;
1402 *p2 = mapStatisticalEndTime(grid);
1403 if (*p2 == UINT_MAX) {
1406 if (grid->md.stat_proc.t[0].incr_length == 0)
1409 fprintf(stderr,
"Unable to map discrete processing to GRIB1\n");
1417 *p1 = grid->md.fcst_time;
1418 *p2 = mapStatisticalEndTime(grid);
1419 if (*p2 == UINT_MAX) {
1422 if (grid->md.stat_proc.t[0].incr_length == 0)
1425 fprintf(stderr,
"Unable to map discrete processing to GRIB1\n");
1431 if (grid->md.stat_proc.t[0].proc_code == 255 && center == 7) {
1432 if (grid->disc == 0) {
1433 if (grid->md.param_cat == 0) {
1434 switch (grid->md.param_num) {
1438 *p1 = grid->md.fcst_time;
1439 *p2 = mapStatisticalEndTime(grid);
1440 if (*p2 == UINT_MAX) {
1443 if (grid->md.stat_proc.t[0].incr_length == 0)
1447 "Unable to map discrete processing to GRIB1\n");
1455 fprintf(stderr,
"Unable to map statistical process %d to GRIB1\n",
1456 grid->md.stat_proc.t[0].proc_code);
1461 *n_missing = grid->md.stat_proc.nmiss;
1465 "Unable to map time range for Product Definition Template %d "
1467 grid->md.pds_templ_num);
1476void GribV2Record::translateDataType() {
1483 multiplyAllData(3600.0);
1601void GribV2Record::readDataSet(
ZUFILE *file) {
1612 while (strncmp(&((
char *)grib_msg->buffer)[grib_msg->offset / 8],
"7777",
1615 getBits(grib_msg->buffer, &len, grib_msg->offset, 32);
1616 getBits(grib_msg->buffer, &sec_num, grib_msg->offset + 4 * 8, 8);
1619 if (skip ==
true)
break;
1620 ok = unpackLUS(grib_msg);
1623 if (skip ==
true)
break;
1624 ok = unpackGDS(grib_msg);
1626 Ni = grib_msg->md.nx;
1627 Nj = grib_msg->md.ny;
1628 La1 = grib_msg->md.slat;
1629 Lo1 = grib_msg->md.slon;
1630 La2 = grib_msg->md.lats.elat;
1631 Lo2 = grib_msg->md.lons.elon;
1632 Di = grib_msg->md.xinc.loinc;
1633 Dj = grib_msg->md.yinc.lainc;
1634 scan_flags = grib_msg->md.scan_mode;
1635 is_scan_i_positive = (scan_flags & 0x80) == 0;
1636 is_scan_j_positive = (scan_flags & 0x40) != 0;
1637 is_adjacent_i = (scan_flags & 0x20) == 0;
1642 if (is_scan_i_positive)
1660 if (Ni <= 1 || Nj <= 1) {
1661 erreur(
"Record %d: Ni=%d Nj=%d",
id, Ni, Nj);
1664 Di = (
Lo2 -
Lo1) / (Ni - 1);
1665 Dj = (La2 - La1) / (Nj - 1);
1670 if (skip ==
true)
break;
1671 ok = unpackPDS(grib_msg);
1676 productTemplate = grib_msg->md.pds_templ_num;
1677 dataCat = grib_msg->md.param_cat;
1678 dataNum = grib_msg->md.param_num;
1679 data_type = GRBV2_TO_DATA(productDiscipline, dataCat, dataNum);
1688 if (grib_msg->md.lvl2_type == 8 && grib_msg->md.lvl1_type == 1) {
1693 int n_avg, n_missing;
1702 SetRecordCurrentDate(MakeDate(
refyear, refmonth, refday, refhour,
1711 if (skip ==
true)
break;
1712 ok = unpackDRS(grib_msg);
1715 if (skip ==
true)
break;
1716 ok = unpackBMS(grib_msg);
1718 if (grib_msg->md.bmssize != 0) {
1720 bms_size = grib_msg->md.bmssize;
1721 bms_bits =
new zuchar[grib_msg->md.bmssize];
1722 memcpy(bms_bits, grib_msg->md.bms, grib_msg->md.bmssize);
1727 if (skip ==
false) {
1728 ok = unpackDS(grib_msg);
1730 data = grib_msg->grids.gridpoints;
1731 grib_msg->grids.gridpoints = 0;
1734 if (grib_msg->num_grids != 1) DS =
true;
1737 grib_msg->offset += len * 8;
1738 if (
ok ==
false || DS ==
true)
break;
1744 printf(
"==== GV2 %d\n",
ok);
1745 printf(
"Lo1=%f Lo2=%f La1=%f La2=%f\n",
Lo1,
Lo2, La1, La2);
1746 printf(
"Lo1=%f Lo2=%f La1=%f La2=%f\n", grib_msg->md.slon,
1747 grib_msg->md.lons.elon, grib_msg->md.slat, grib_msg->md.lats.elat);
1748 printf(
"Ni=%d Nj=%d\n", Ni, Nj);
1749 printf(
"has_di_dj=%d Di,Dj=(%f %f)\n", has_di_dj, Di, Dj);
1750 printf(
"is_scan_i_positive=%d is_scan_j_positive=%d is_adjacent_i=%d\n",
1751 is_scan_i_positive, is_scan_j_positive, is_adjacent_i);
1752 printf(
"hasBMS=%d\n",
hasBMS);
1756 translateDataType();
1761 strncmp(&((
char *)grib_msg->buffer)[grib_msg->offset / 8],
"7777", 4) ==
1769GribV2Record::GribV2Record(
ZUFILE *file,
int id_) {
1771 seekStart = zu_tell(file);
1779 long start = seekStart;
1786 if (zu_read(file, strgrib, 4) != 4) {
1792 bool b_haveReadGRIB =
false;
1794 if (strncmp(strgrib,
"GRIB", 4) != 0)
1797 b_len_add_8 =
false;
1798 b_haveReadGRIB =
true;
1802 if ((strgrib[0] == 0) && (strgrib[1] == 0) && (strgrib[2] == 0) &&
1803 (strgrib[3] == 0)) {
1804 b_len_add_8 =
false;
1805 b_haveReadGRIB =
false;
1807 ok = readGribSection0_IS(file,
1812 unpackIDS(grib_msg);
1815 off = grib_msg->offset / 8;
1816 while (strncmp(&((
char *)grib_msg->buffer)[off],
"7777", 4) != 0) {
1817 len = uint4(grib_msg->buffer + off);
1818 sec_num = grib_msg->buffer[off + 4];
1819 if (sec_num == 7) grib_msg->num_grids++;
1824 (void)zu_seek(file, start, SEEK_SET);
1828 refmonth = grib_msg->mo;
1829 refday = grib_msg->dy;
1830 refhour = grib_msg->time / 10000;
1831 refminute = (grib_msg->time / 100) % 100;
1832 ref_date = MakeDate(
refyear, refmonth, refday, refhour, refminute, 0);
1833 sprintf(str_ref_date,
"%04d-%02d-%02d %02d:%02d",
refyear, refmonth, refday,
1834 refhour, refminute);
1838 productDiscipline = grib_msg->disc;
1843bool GribV2Record::hasMoreDataSet()
const {
1844 return grib_msg && grib_msg->num_grids != 1 ? true :
false;
1851 delete[] rec1->data;
1852 delete[] rec1->bms_bits;
1856 rec1->readDataSet(file);
1863#pragma warning(disable : 4717)
1866#pragma warning(default : 4717)
1869GribV2Record::~GribV2Record() {
delete grib_msg; }
1878 unsigned char temp[16];
1882 if (grib_msg->buffer !=
nullptr) {
1883 delete[] grib_msg->buffer;
1884 grib_msg->buffer =
nullptr;
1886 grib_msg->num_grids = 0;
1888 if ((status = zu_read(fp, &temp[4], 12)) != 12) {
1891 grib_msg->disc = temp[6];
1892 grib_msg->ed_num = temp[7];
1895 if (grib_msg->ed_num != 2)
return false;
1897 getBits(temp, &grib_msg->total_len, 96, 32);
1899 if (grib_msg->total_len < 16 || grib_msg->total_len > (INT_MAX - 4))
1902 grib_msg->md.nx = grib_msg->md.ny = 0;
1903 grib_msg->buffer =
new unsigned char[grib_msg->total_len + 4];
1904 memcpy(grib_msg->buffer, temp, 16);
1905 num = grib_msg->total_len - 16;
1907 status = zu_read(fp, &grib_msg->buffer[16], num);
1908 if (status != (
int)num)
return false;
1910 if (strncmp(&((
char *)grib_msg->buffer)[grib_msg->total_len - 4],
"7777",
1912 fprintf(stderr,
"Warning: no end section found\n");
1914 grib_msg->offset = 128;
1918bool GribV2Record::readGribSection0_IS(
ZUFILE *file,
bool b_skip_initial_GRIB) {
1920 fileOffset0 = zu_tell(file);
1922 if (!b_skip_initial_GRIB) {
1924 while ((zu_read(file, strgrib, 1) == 1) && (strgrib[0] !=
'G')) {
1927 if (strgrib[0] !=
'G') {
1932 if (zu_read(file, strgrib + 1, 3) != 3) {
1937 if (strncmp(strgrib,
"GRIB", 4) != 0) {
1938 printf(
"readGribSection0_IS(): Unknown file header : %c%c%c%c\n",
1939 strgrib[0], strgrib[1], strgrib[2], strgrib[3]);
1946 seekStart = zu_tell(file) - 4;
1948 if (unpackIS(file, grib_msg) ==
false) {
1967zuint GribV2Record::periodSeconds(zuchar
unit, zuint P1, zuint P2,
1999 erreur(
"id=%d: unknown time unit in PDS b18=%d",
id,
unit);
2003 grib_debug(
"id=%d: PDS unit %d (time range) b21=%d %d P1=%d P2=%d\n",
id,
2004 unit, range, res, P1, P2);
2026 dur = ((zuint)P1 << 8) + (zuint)P2;
2029 erreur(
"id=%d: unknown time range in PDS b21=%d",
id, range);
A meteorological data grid from a GRIB (Gridded Binary) file.
bool eof
Signals when the end of the GRIB file has been reached during parsing.
zuint periodsec
Forecast period in seconds.
bool is_duplicated
Indicates if this record was created through copying rather than direct reading.
double Lo2
Grid end coordinates.
zuint period_p1
Time range indicators for this forecast step.
double Lo1
Grid origin coordinates.
zuchar id_model
Model identifier within the originating center.
zuchar GetDataType() const
Returns the type of meteorological parameter stored in this grid.
zuchar id_grid
Grid identifier used by the originating center.
bool ok
Indicates record validity.
int id
Unique identifier for this record.
bool hasBMS
Indicates presence of a bitmap section.
zuint level_value
Numeric value associated with level_type.
zuint GetLevelValue() const
Returns the numeric value associated with the level type.
zuint refyear
Components of the reference time for this forecast.
zuchar data_type
Parameter identifier as defined by GRIB tables.
time_t ref_date
Unix timestamp of model initialization time.
zuchar level_type
Vertical level type indicator.
bool known_data
Indicates whether the data type in this record is recognized by the parser.
int data_center_model
Identifies the numerical weather model that produced this data.
zuchar id_center
Originating center ID as defined by WMO common table C-1.
zuchar edition_number
GRIB edition number, indicating the version of the GRIB specification used.
zuchar time_range
Statistical processing indicator.
zuchar GetLevelType() const
Returns the type of vertical level for this grid's data.
GRIB Version 2 Record Implementation.