1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
/**
* Copyright 1981-2007 ECMWF
*
* Licensed under the GNU Lesser General Public License which
* incorporates the terms and conditions of version 3 of the GNU
* General Public License.
* See LICENSE and gpl-3.0.txt for details.
*/
#include <stdio.h>
#include <string.h>
#include "fortint.h"
/* defines for FORTRAN subroutine */
#ifndef CRAY
#ifdef FORTRAN_NO_UNDERSCORE
#define SOFFSET soffset
#else
#define SOFFSET soffset_
#endif
#endif
#define ERROR(a,b) {perror(a);return b;}
#define GRIB 0x47524942
#define len3oct(p) ((((long)*(p))<<16) + (((long)*(p+1))<<8) + (long)*(p+2))
#define BIT1 0x80
#define BIT2 0x40
#define BIT3 0x20
#define BIT4 0x10
#define BIT5 0x08
#define BIT6 0x04
#define BIT7 0x02
#define BIT8 0x01
static int grab(unsigned char * , unsigned char * , long ,long ,long * );
fortint soffset_(
unsigned char * buffer,
fortint* is0,
fortint* is1,
fortint* is2,
fortint* is3,
fortint* is4,
fortint* iedition) {
long s0, s1, s2, s3, s4, edition;
int large = 0;
int found = 0;
int code = 0;
long bytes_read = 0, advance;
unsigned char p, edit_num, flag23;
unsigned char size[3];
int section0 = 8, section1, section2, section3, section4;
long total;
unsigned char grp_7777[5];
/* Read bytes until "GRIB" found */
do
{
if( grab(buffer, &p, 1, 1, &bytes_read) != 0) return 1;
code = ( (code << 8) + p ) & 0xFFFFFFFF;
if (code == GRIB ) found = 1;
} while ( ! found );
s0 = bytes_read - 4;
bytes_read = 4;
/* Now find out which edition of GRIB is present (default is 1) */
edition = 1;
s1 = s0 + 8;
if( (*(buffer+21-s0) == '\0') && (*(buffer+22-s0) == '\0') )
{
edition = -1; /* GRIB edition -1 */
s1 = s0;
section1 = 20;
section0 = 4;
}
else
{
if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
total = len3oct(size);
if( total == 24 )
{
/* Move past the edition number */
if( grab(buffer, &edit_num, 1, 1, &bytes_read) != 0) return 1;
edition = 0; /* GRIB edition 0 */
section1 = 24;
s1 = s0 + 4;
section0 = 4;
}
}
if( edition == 1 )
{
/* See if it is an extra large (wave) product */
if( total > 0x800000 ) {
total = (total&0x7fffff) * 120;
large = 1;
}
/* Move past the edition number */
if( grab(buffer, &edit_num, 1, 1, &bytes_read) != 0) return 1;
/* Read length of section 1 */
if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
section1 = len3oct(size);
}
/* Now figure out if sections 2/3 are present */
advance = 4;
bytes_read += advance;
if( grab(buffer, &flag23, 1, 1, &bytes_read) != 0) return 1;
section2 = flag23 & BIT1;
section3 = flag23 & BIT2;
/* Advance to end of section 1 */
advance = section1 - (bytes_read - section0);
bytes_read += advance;
/* Read section 2 length if it is given*/
if( section2 )
{
s2 = s0 + bytes_read;
if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
section2 = len3oct(size);
advance = section2 - (bytes_read - section0 - section1);
bytes_read += advance;
}
else
{
section2 = 0;
s2 = 0;
}
/* Read section 3 length if it is given*/
if( section3 )
{
s3 = s0 + bytes_read;
if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
section3 = len3oct(size);
advance = section3 - (bytes_read - section0 - section1 - section2);
bytes_read += advance;
}
else
{
section3 = 0;
s3 = 0;
}
/* Read section 4 length */
s4 = s0 + bytes_read;
if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
section4 = len3oct(size);
if( large ) section4 = total + 3 - bytes_read - section4;
advance = section4 - (bytes_read - section0 - section1 - section2 - section3);
bytes_read += advance;
/* Check 7777 group is in the expected place */
if( grab(buffer, grp_7777, 4, 1, &bytes_read) != 0) return 1;
grp_7777[4] = '\0';
if( strcmp((char *)grp_7777,"7777") != 0 )
ERROR("7777 group not found", 15);
/* Success! */
*is0 = (fortint) s0;
*is1 = (fortint) s1;
*is2 = (fortint) s2;
*is3 = (fortint) s3;
*is4 = (fortint) s4;
*iedition = (fortint) edition;
return 0;
}
fortint soffset(
unsigned char * buffer,
fortint* is0,
fortint* is1,
fortint* is2,
fortint* is3,
fortint* is4,
fortint* iedition) {
return soffset_(buffer,is0,is1,is2,is3,is4,iedition);
}
static int grab(unsigned char * buffer, unsigned char * where, long size,long cnt,long * num_bytes_read)
{
long number = size*cnt;
memcpy(where, (buffer+(*num_bytes_read)), number);
*num_bytes_read += number;
return 0;
}
|