1 /*
2 * Copyright 2005-2018 ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8 * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9 */
10
11 /************************************
12 * Enrico Fucile
13 ************************************/
14
15 #include "grib_api_internal.h"
16 /*
17 This is used by make_class.pl
18
19 START_CLASS_DEF
20 CLASS = accessor
21 SUPER = grib_accessor_class_gen
22 IMPLEMENTS = pack_long;
23 IMPLEMENTS = init;get_native_type
24 MEMBERS = const char* values
25 MEMBERS = const char* Ni
26 MEMBERS = const char* Nj
27 MEMBERS = const char* i_scans_negatively
28 MEMBERS = const char* j_scans_positively
29 MEMBERS = const char* first
30 MEMBERS = const char* last
31 MEMBERS = const char* axis
32 END_CLASS_DEF
33
34 */
35
36 /* START_CLASS_IMP */
37
38 /*
39
40 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
41 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
42 or edit "accessor.class" and rerun ./make_class.pl
43
44 */
45
46 static int get_native_type(grib_accessor*);
47 static int pack_long(grib_accessor*, const long* val,size_t *len);
48 static void init(grib_accessor*,const long, grib_arguments* );
49 static void init_class(grib_accessor_class*);
50
51 typedef struct grib_accessor_change_scanning_direction {
52 grib_accessor att;
53 /* Members defined in gen */
54 /* Members defined in change_scanning_direction */
55 const char* values;
56 const char* Ni;
57 const char* Nj;
58 const char* i_scans_negatively;
59 const char* j_scans_positively;
60 const char* first;
61 const char* last;
62 const char* axis;
63 } grib_accessor_change_scanning_direction;
64
65 extern grib_accessor_class* grib_accessor_class_gen;
66
67 static grib_accessor_class _grib_accessor_class_change_scanning_direction = {
68 &grib_accessor_class_gen, /* super */
69 "change_scanning_direction", /* name */
70 sizeof(grib_accessor_change_scanning_direction), /* size */
71 0, /* inited */
72 &init_class, /* init_class */
73 &init, /* init */
74 0, /* post_init */
75 0, /* free mem */
76 0, /* describes himself */
77 0, /* get length of section */
78 0, /* get length of string */
79 0, /* get number of values */
80 0, /* get number of bytes */
81 0, /* get offset to bytes */
82 &get_native_type, /* get native type */
83 0, /* get sub_section */
84 0, /* grib_pack procedures long */
85 0, /* grib_pack procedures long */
86 &pack_long, /* grib_pack procedures long */
87 0, /* grib_unpack procedures long */
88 0, /* grib_pack procedures double */
89 0, /* grib_unpack procedures double */
90 0, /* grib_pack procedures string */
91 0, /* grib_unpack procedures string */
92 0, /* grib_pack procedures bytes */
93 0, /* grib_unpack procedures bytes */
94 0, /* pack_expression */
95 0, /* notify_change */
96 0, /* update_size */
97 0, /* preferred_size */
98 0, /* resize */
99 0, /* nearest_smaller_value */
100 0, /* next accessor */
101 0, /* compare vs. another accessor */
102 0, /* unpack only ith value */
103 0, /* unpack a subarray */
104 0, /* clear */
105 };
106
107
108 grib_accessor_class* grib_accessor_class_change_scanning_direction = &_grib_accessor_class_change_scanning_direction;
109
110
init_class(grib_accessor_class * c)111 static void init_class(grib_accessor_class* c)
112 {
113 c->dump = (*(c->super))->dump;
114 c->next_offset = (*(c->super))->next_offset;
115 c->string_length = (*(c->super))->string_length;
116 c->value_count = (*(c->super))->value_count;
117 c->byte_count = (*(c->super))->byte_count;
118 c->byte_offset = (*(c->super))->byte_offset;
119 c->sub_section = (*(c->super))->sub_section;
120 c->pack_missing = (*(c->super))->pack_missing;
121 c->is_missing = (*(c->super))->is_missing;
122 c->unpack_long = (*(c->super))->unpack_long;
123 c->pack_double = (*(c->super))->pack_double;
124 c->unpack_double = (*(c->super))->unpack_double;
125 c->pack_string = (*(c->super))->pack_string;
126 c->unpack_string = (*(c->super))->unpack_string;
127 c->pack_bytes = (*(c->super))->pack_bytes;
128 c->unpack_bytes = (*(c->super))->unpack_bytes;
129 c->pack_expression = (*(c->super))->pack_expression;
130 c->notify_change = (*(c->super))->notify_change;
131 c->update_size = (*(c->super))->update_size;
132 c->preferred_size = (*(c->super))->preferred_size;
133 c->resize = (*(c->super))->resize;
134 c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
135 c->next = (*(c->super))->next;
136 c->compare = (*(c->super))->compare;
137 c->unpack_double_element = (*(c->super))->unpack_double_element;
138 c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
139 c->clear = (*(c->super))->clear;
140 }
141
142 /* END_CLASS_IMP */
143
init(grib_accessor * a,const long len,grib_arguments * args)144 static void init(grib_accessor* a, const long len , grib_arguments* args )
145 {
146 int n=0;
147 grib_accessor_change_scanning_direction* self= (grib_accessor_change_scanning_direction*)a;
148
149 self->values=grib_arguments_get_name(a->parent->h,args,n++);
150 self->Ni=grib_arguments_get_name(a->parent->h,args,n++);
151 self->Nj=grib_arguments_get_name(a->parent->h,args,n++);
152 self->i_scans_negatively=grib_arguments_get_name(a->parent->h,args,n++);
153 self->j_scans_positively=grib_arguments_get_name(a->parent->h,args,n++);
154 self->first=grib_arguments_get_name(a->parent->h,args,n++);
155 self->last=grib_arguments_get_name(a->parent->h,args,n++);
156 self->axis=grib_arguments_get_name(a->parent->h,args,n++);
157
158 a->flags |= GRIB_ACCESSOR_FLAG_FUNCTION;
159 a->length = 0;
160 }
161
pack_long(grib_accessor * a,const long * val,size_t * len)162 static int pack_long(grib_accessor* a, const long* val, size_t *len)
163 {
164 int ret=0;
165 long i,j,jr,theEnd,Ni,Nj,k,kp;
166 double tmp;
167 long iScansNegatively=0;
168 long jScansPositively=0;
169 double first=0;
170 double last=0;
171 size_t size=0;
172 double* values=NULL;
173 grib_accessor_change_scanning_direction* self= (grib_accessor_change_scanning_direction*)a;
174 grib_context* c=a->parent->h->context;
175 grib_handle* h=a->parent->h;
176
177 if (*val==0) return 0;
178
179 if((ret = grib_get_long_internal(h,self->Ni,&Ni)) != GRIB_SUCCESS) return ret;
180 if((ret = grib_get_long_internal(h,self->Nj,&Nj)) != GRIB_SUCCESS) return ret;
181
182 if((ret = grib_get_long_internal(h,self->i_scans_negatively,&iScansNegatively)) != GRIB_SUCCESS) return ret;
183 if((ret = grib_get_long_internal(h,self->j_scans_positively,&jScansPositively)) != GRIB_SUCCESS) return ret;
184
185 if((ret = grib_get_double_internal(h,self->first,&first)) != GRIB_SUCCESS) return ret;
186 if((ret = grib_get_double_internal(h,self->last,&last)) != GRIB_SUCCESS) return ret;
187
188 if ( (ret=grib_get_size(h,self->values,&size)) != GRIB_SUCCESS) return ret;
189
190 if (size>Ni*Nj) {
191 grib_context_log(c,GRIB_LOG_ERROR,"change_scanning_direction: wrong values size!=Ni*Nj (%ld!=%ld*%ld)",size,Ni,Nj);
192 return GRIB_WRONG_ARRAY_SIZE;
193 }
194
195 values=(double*)grib_context_malloc(c,size*sizeof(double));
196 if (!values) return GRIB_OUT_OF_MEMORY;
197
198 if((ret = grib_get_double_array_internal(h,self->values,values,&size))
199 != GRIB_SUCCESS) {
200 grib_context_free(c,values);
201 return ret;
202 }
203
204 if (self->axis[0] == 'x') {
205 theEnd=(Ni+0.5)/2;
206 for (j=0;j<Nj;j++) {
207 jr=Ni*j;
208 for (i=0;i<theEnd;i++) {
209 k=jr+i;
210 kp=jr+Ni-i-1;
211 tmp=values[k];
212 values[k]=values[kp];
213 values[kp]=tmp;
214 }
215 }
216 iScansNegatively=!iScansNegatively;
217 if((ret = grib_set_long_internal(h,self->i_scans_negatively,iScansNegatively))
218 != GRIB_SUCCESS) return ret;
219 } else {
220 long kpj;
221 theEnd=(Nj+0.5)/2;
222 for (i=0;i<Ni;i++) {
223 kpj=Ni*(Nj-1);
224 for (j=0;j<theEnd;j++) {
225 k=Ni*j+i;
226 kp=kpj-Ni*j+i;
227 tmp=values[k];
228 values[k]=values[kp];
229 values[kp]=tmp;
230 }
231 }
232 jScansPositively=!jScansPositively;
233 if((ret = grib_set_long_internal(h,self->j_scans_positively,jScansPositively))
234 != GRIB_SUCCESS) return ret;
235 }
236
237 if((ret = grib_set_double_array_internal(h,self->values,values,size)) != GRIB_SUCCESS) {
238 grib_context_free(c,values);
239 return ret;
240 }
241
242 if((ret = grib_set_double_internal(h,self->first,last)) != GRIB_SUCCESS) return ret;
243
244 if((ret = grib_set_double_internal(h,self->last,first)) != GRIB_SUCCESS) return ret;
245
246 grib_context_free(c,values);
247
248 return GRIB_SUCCESS;
249 }
250
get_native_type(grib_accessor * a)251 static int get_native_type(grib_accessor* a)
252 {
253 return GRIB_TYPE_LONG;
254 }
255