WCSLIB  5.4.1
tab.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 5.5 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2015, Mark Calabretta
5 
6  This file is part of WCSLIB.
7 
8  WCSLIB is free software: you can redistribute it and/or modify it under the
9  terms of the GNU Lesser General Public License as published by the Free
10  Software Foundation, either version 3 of the License, or (at your option)
11  any later version.
12 
13  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with WCSLIB. If not, see http://www.gnu.org/licenses.
20 
21  Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22 
23  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24  http://www.atnf.csiro.au/people/Mark.Calabretta
25  $Id: tab.h,v 5.5 2015/05/05 13:16:31 mcalabre Exp $
26 *=============================================================================
27 *
28 * WCSLIB 5.5 - C routines that implement the FITS World Coordinate System
29 * (WCS) standard. Refer to the README file provided with WCSLIB for an
30 * overview of the library.
31 *
32 *
33 * Summary of the tab routines
34 * ---------------------------
35 * Routines in this suite implement the part of the FITS World Coordinate
36 * System (WCS) standard that deals with tabular coordinates, i.e. coordinates
37 * that are defined via a lookup table, as described in
38 *
39 = "Representations of world coordinates in FITS",
40 = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I)
41 =
42 = "Representations of spectral coordinates in FITS",
43 = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
44 = 2006, A&A, 446, 747 (WCS Paper III)
45 *
46 * These routines define methods to be used for computing tabular world
47 * coordinates from intermediate world coordinates (a linear transformation
48 * of image pixel coordinates), and vice versa. They are based on the tabprm
49 * struct which contains all information needed for the computations. The
50 * struct contains some members that must be set by the user, and others that
51 * are maintained by these routines, somewhat like a C++ class but with no
52 * encapsulation.
53 *
54 * tabini(), tabmem(), tabcpy(), and tabfree() are provided to manage the
55 * tabprm struct, and another, tabprt(), to print its contents.
56 *
57 * A setup routine, tabset(), computes intermediate values in the tabprm struct
58 * from parameters in it that were supplied by the user. The struct always
59 * needs to be set up by tabset() but it need not be called explicitly - refer
60 * to the explanation of tabprm::flag.
61 *
62 * tabx2s() and tabs2x() implement the WCS tabular coordinate transformations.
63 *
64 * Accuracy:
65 * ---------
66 * No warranty is given for the accuracy of these routines (refer to the
67 * copyright notice); intending users must satisfy for themselves their
68 * adequacy for the intended purpose. However, closure effectively to within
69 * double precision rounding error was demonstrated by test routine ttab.c
70 * which accompanies this software.
71 *
72 *
73 * tabini() - Default constructor for the tabprm struct
74 * ----------------------------------------------------
75 * tabini() allocates memory for arrays in a tabprm struct and sets all members
76 * of the struct to default values.
77 *
78 * PLEASE NOTE: every tabprm struct should be initialized by tabini(), possibly
79 * repeatedly. On the first invokation, and only the first invokation, the
80 * flag member of the tabprm struct must be set to -1 to initialize memory
81 * management, regardless of whether tabini() will actually be used to allocate
82 * memory.
83 *
84 * Given:
85 * alloc int If true, allocate memory unconditionally for arrays in
86 * the tabprm struct.
87 *
88 * If false, it is assumed that pointers to these arrays
89 * have been set by the user except if they are null
90 * pointers in which case memory will be allocated for
91 * them regardless. (In other words, setting alloc true
92 * saves having to initalize these pointers to zero.)
93 *
94 * M int The number of tabular coordinate axes.
95 *
96 * K const int[]
97 * Vector of length M whose elements (K_1, K_2,... K_M)
98 * record the lengths of the axes of the coordinate array
99 * and of each indexing vector. M and K[] are used to
100 * determine the length of the various tabprm arrays and
101 * therefore the amount of memory to allocate for them.
102 * Their values are copied into the tabprm struct.
103 *
104 * It is permissible to set K (i.e. the address of the
105 * array) to zero which has the same effect as setting
106 * each element of K[] to zero. In this case no memory
107 * will be allocated for the index vectors or coordinate
108 * array in the tabprm struct. These together with the
109 * K vector must be set separately before calling
110 * tabset().
111 *
112 * Given and returned:
113 * tab struct tabprm*
114 * Tabular transformation parameters. Note that, in
115 * order to initialize memory management tabprm::flag
116 * should be set to -1 when tab is initialized for the
117 * first time (memory leaks may result if it had already
118 * been initialized).
119 *
120 * Function return value:
121 * int Status return value:
122 * 0: Success.
123 * 1: Null tabprm pointer passed.
124 * 2: Memory allocation failed.
125 * 3: Invalid tabular parameters.
126 *
127 * For returns > 1, a detailed error message is set in
128 * tabprm::err if enabled, see wcserr_enable().
129 *
130 *
131 * tabmem() - Acquire tabular memory
132 * ---------------------------------
133 * tabmem() takes control of memory allocated by the user for arrays in the
134 * tabprm struct.
135 *
136 * Given and returned:
137 * tab struct tabprm*
138 * Tabular transformation parameters.
139 *
140 * Function return value:
141 * int Status return value:
142 * 0: Success.
143 * 1: Null tabprm pointer passed.
144 * 2: Memory allocation failed.
145 *
146 * For returns > 1, a detailed error message is set in
147 * tabprm::err if enabled, see wcserr_enable().
148 *
149 *
150 * tabcpy() - Copy routine for the tabprm struct
151 * ---------------------------------------------
152 * tabcpy() does a deep copy of one tabprm struct to another, using tabini() to
153 * allocate memory for its arrays if required. Only the "information to be
154 * provided" part of the struct is copied; a call to tabset() is required to
155 * set up the remainder.
156 *
157 * Given:
158 * alloc int If true, allocate memory unconditionally for arrays in
159 * the tabprm struct.
160 *
161 * If false, it is assumed that pointers to these arrays
162 * have been set by the user except if they are null
163 * pointers in which case memory will be allocated for
164 * them regardless. (In other words, setting alloc true
165 * saves having to initalize these pointers to zero.)
166 *
167 * tabsrc const struct tabprm*
168 * Struct to copy from.
169 *
170 * Given and returned:
171 * tabdst struct tabprm*
172 * Struct to copy to. tabprm::flag should be set to -1
173 * if tabdst was not previously initialized (memory leaks
174 * may result if it was previously initialized).
175 *
176 * Function return value:
177 * int Status return value:
178 * 0: Success.
179 * 1: Null tabprm pointer passed.
180 * 2: Memory allocation failed.
181 *
182 * For returns > 1, a detailed error message is set in
183 * tabprm::err (associated with tabdst) if enabled, see
184 * wcserr_enable().
185 *
186 *
187 * tabcmp() - Compare two tabprm structs for equality
188 * --------------------------------------------------
189 * tabcmp() compares two tabprm structs for equality.
190 *
191 * Given:
192 * cmp int A bit field controlling the strictness of the
193 * comparison. At present, this value must always be 0,
194 * indicating a strict comparison. In the future, other
195 * options may be added.
196 *
197 * tol double Tolerance for comparison of floating-point values.
198 * For example, for tol == 1e-6, all floating-point
199 * values in the structs must be equal to the first 6
200 * decimal places. A value of 0 implies exact equality.
201 *
202 * tab1 const struct tabprm*
203 * The first tabprm struct to compare.
204 *
205 * tab2 const struct tabprm*
206 * The second tabprm struct to compare.
207 *
208 * Returned:
209 * equal int* Non-zero when the given structs are equal.
210 *
211 * Function return value:
212 * int Status return value:
213 * 0: Success.
214 * 1: Null pointer passed.
215 *
216 *
217 * tabfree() - Destructor for the tabprm struct
218 * --------------------------------------------
219 * tabfree() frees memory allocated for the tabprm arrays by tabini().
220 * tabini() records the memory it allocates and tabfree() will only attempt to
221 * free this.
222 *
223 * PLEASE NOTE: tabfree() must not be invoked on a tabprm struct that was not
224 * initialized by tabini().
225 *
226 * Returned:
227 * tab struct tabprm*
228 * Coordinate transformation parameters.
229 *
230 * Function return value:
231 * int Status return value:
232 * 0: Success.
233 * 1: Null tabprm pointer passed.
234 *
235 *
236 * tabprt() - Print routine for the tabprm struct
237 * ----------------------------------------------
238 * tabprt() prints the contents of a tabprm struct using wcsprintf(). Mainly
239 * intended for diagnostic purposes.
240 *
241 * Given:
242 * tab const struct tabprm*
243 * Tabular transformation parameters.
244 *
245 * Function return value:
246 * int Status return value:
247 * 0: Success.
248 * 1: Null tabprm pointer passed.
249 *
250 *
251 * tabset() - Setup routine for the tabprm struct
252 * -----------------------------------------------
253 * tabset() allocates memory for work arrays in the tabprm struct and sets up
254 * the struct according to information supplied within it.
255 *
256 * Note that this routine need not be called directly; it will be invoked by
257 * tabx2s() and tabs2x() if tabprm::flag is anything other than a predefined
258 * magic value.
259 *
260 * Given and returned:
261 * tab struct tabprm*
262 * Tabular transformation parameters.
263 *
264 * Function return value:
265 * int Status return value:
266 * 0: Success.
267 * 1: Null tabprm pointer passed.
268 * 3: Invalid tabular parameters.
269 *
270 * For returns > 1, a detailed error message is set in
271 * tabprm::err if enabled, see wcserr_enable().
272 *
273 *
274 * tabx2s() - Pixel-to-world transformation
275 * ----------------------------------------
276 * tabx2s() transforms intermediate world coordinates to world coordinates
277 * using coordinate lookup.
278 *
279 * Given and returned:
280 * tab struct tabprm*
281 * Tabular transformation parameters.
282 *
283 * Given:
284 * ncoord,
285 * nelem int The number of coordinates, each of vector length
286 * nelem.
287 *
288 * x const double[ncoord][nelem]
289 * Array of intermediate world coordinates, SI units.
290 *
291 * Returned:
292 * world double[ncoord][nelem]
293 * Array of world coordinates, in SI units.
294 *
295 * stat int[ncoord]
296 * Status return value status for each coordinate:
297 * 0: Success.
298 * 1: Invalid intermediate world coordinate.
299 *
300 * Function return value:
301 * int Status return value:
302 * 0: Success.
303 * 1: Null tabprm pointer passed.
304 * 3: Invalid tabular parameters.
305 * 4: One or more of the x coordinates were invalid,
306 * as indicated by the stat vector.
307 *
308 * For returns > 1, a detailed error message is set in
309 * tabprm::err if enabled, see wcserr_enable().
310 *
311 *
312 * tabs2x() - World-to-pixel transformation
313 * ----------------------------------------
314 * tabs2x() transforms world coordinates to intermediate world coordinates.
315 *
316 * Given and returned:
317 * tab struct tabprm*
318 * Tabular transformation parameters.
319 *
320 * Given:
321 * ncoord,
322 * nelem int The number of coordinates, each of vector length
323 * nelem.
324 * world const double[ncoord][nelem]
325 * Array of world coordinates, in SI units.
326 *
327 * Returned:
328 * x double[ncoord][nelem]
329 * Array of intermediate world coordinates, SI units.
330 * stat int[ncoord]
331 * Status return value status for each vector element:
332 * 0: Success.
333 * 1: Invalid world coordinate.
334 *
335 * Function return value:
336 * int Status return value:
337 * 0: Success.
338 * 1: Null tabprm pointer passed.
339 * 3: Invalid tabular parameters.
340 * 5: One or more of the world coordinates were
341 * invalid, as indicated by the stat vector.
342 *
343 * For returns > 1, a detailed error message is set in
344 * tabprm::err if enabled, see wcserr_enable().
345 *
346 *
347 * tabprm struct - Tabular transformation parameters
348 * -------------------------------------------------
349 * The tabprm struct contains information required to transform tabular
350 * coordinates. It consists of certain members that must be set by the user
351 * ("given") and others that are set by the WCSLIB routines ("returned"). Some
352 * of the latter are supplied for informational purposes while others are for
353 * internal use only.
354 *
355 * int flag
356 * (Given and returned) This flag must be set to zero whenever any of the
357 * following tabprm structure members are set or changed:
358 *
359 * - tabprm::M (q.v., not normally set by the user),
360 * - tabprm::K (q.v., not normally set by the user),
361 * - tabprm::map,
362 * - tabprm::crval,
363 * - tabprm::index,
364 * - tabprm::coord.
365 *
366 * This signals the initialization routine, tabset(), to recompute the
367 * returned members of the tabprm struct. tabset() will reset flag to
368 * indicate that this has been done.
369 *
370 * PLEASE NOTE: flag should be set to -1 when tabini() is called for the
371 * first time for a particular tabprm struct in order to initialize memory
372 * management. It must ONLY be used on the first initialization otherwise
373 * memory leaks may result.
374 *
375 * int M
376 * (Given or returned) Number of tabular coordinate axes.
377 *
378 * If tabini() is used to initialize the tabprm struct (as would normally
379 * be the case) then it will set M from the value passed to it as a
380 * function argument. The user should not subsequently modify it.
381 *
382 * int *K
383 * (Given or returned) Pointer to the first element of a vector of length
384 * tabprm::M whose elements (K_1, K_2,... K_M) record the lengths of the
385 * axes of the coordinate array and of each indexing vector.
386 *
387 * If tabini() is used to initialize the tabprm struct (as would normally
388 * be the case) then it will set K from the array passed to it as a
389 * function argument. The user should not subsequently modify it.
390 *
391 * int *map
392 * (Given) Pointer to the first element of a vector of length tabprm::M
393 * that defines the association between axis m in the M-dimensional
394 * coordinate array (1 <= m <= M) and the indices of the intermediate world
395 * coordinate and world coordinate arrays, x[] and world[], in the argument
396 * lists for tabx2s() and tabs2x().
397 *
398 * When x[] and world[] contain the full complement of coordinate elements
399 * in image-order, as will usually be the case, then map[m-1] == i-1 for
400 * axis i in the N-dimensional image (1 <= i <= N). In terms of the FITS
401 * keywords
402 *
403 * map[PVi_3a - 1] == i - 1.
404 *
405 * However, a different association may result if x[], for example, only
406 * contains a (relevant) subset of intermediate world coordinate elements.
407 * For example, if M == 1 for an image with N > 1, it is possible to fill
408 * x[] with the relevant coordinate element with nelem set to 1. In this
409 * case map[0] = 0 regardless of the value of i.
410 *
411 * double *crval
412 * (Given) Pointer to the first element of a vector of length tabprm::M
413 * whose elements contain the index value for the reference pixel for each
414 * of the tabular coordinate axes.
415 *
416 * double **index
417 * (Given) Pointer to the first element of a vector of length tabprm::M of
418 * pointers to vectors of lengths (K_1, K_2,... K_M) of 0-relative indexes
419 * (see tabprm::K).
420 *
421 * The address of any or all of these index vectors may be set to zero,
422 * i.e.
423 *
424 = index[m] == 0;
425 *
426 * this is interpreted as default indexing, i.e.
427 *
428 = index[m][k] = k;
429 *
430 * double *coord
431 * (Given) Pointer to the first element of the tabular coordinate array,
432 * treated as though it were defined as
433 *
434 = double coord[K_M]...[K_2][K_1][M];
435 *
436 * (see tabprm::K) i.e. with the M dimension varying fastest so that the
437 * M elements of a coordinate vector are stored contiguously in memory.
438 *
439 * int nc
440 * (Returned) Total number of coordinate vectors in the coordinate array
441 * being the product K_1 * K_2 * ... * K_M (see tabprm::K).
442 *
443 * int padding
444 * (An unused variable inserted for alignment purposes only.)
445 *
446 * int *sense
447 * (Returned) Pointer to the first element of a vector of length tabprm::M
448 * whose elements indicate whether the corresponding indexing vector is
449 * monotonic increasing (+1), or decreasing (-1).
450 *
451 * int *p0
452 * (Returned) Pointer to the first element of a vector of length tabprm::M
453 * of interpolated indices into the coordinate array such that Upsilon_m,
454 * as defined in Paper III, is equal to (p0[m] + 1) + tabprm::delta[m].
455 *
456 * double *delta
457 * (Returned) Pointer to the first element of a vector of length tabprm::M
458 * of interpolated indices into the coordinate array such that Upsilon_m,
459 * as defined in Paper III, is equal to (tabprm::p0[m] + 1) + delta[m].
460 *
461 * double *extrema
462 * (Returned) Pointer to the first element of an array that records the
463 * minimum and maximum value of each element of the coordinate vector in
464 * each row of the coordinate array, treated as though it were defined as
465 *
466 = double extrema[K_M]...[K_2][2][M]
467 *
468 * (see tabprm::K). The minimum is recorded in the first element of the
469 * compressed K_1 dimension, then the maximum. This array is used by the
470 * inverse table lookup function, tabs2x(), to speed up table searches.
471 *
472 * struct wcserr *err
473 * (Returned) If enabled, when an error status is returned, this struct
474 * contains detailed information about the error, see wcserr_enable().
475 *
476 * int m_flag
477 * (For internal use only.)
478 * int m_M
479 * (For internal use only.)
480 * int m_N
481 * (For internal use only.)
482 * int set_M
483 * (For internal use only.)
484 * int m_K
485 * (For internal use only.)
486 * int m_map
487 * (For internal use only.)
488 * int m_crval
489 * (For internal use only.)
490 * int m_index
491 * (For internal use only.)
492 * int m_indxs
493 * (For internal use only.)
494 * int m_coord
495 * (For internal use only.)
496 *
497 *
498 * Global variable: const char *tab_errmsg[] - Status return messages
499 * ------------------------------------------------------------------
500 * Error messages to match the status value returned from each function.
501 *
502 *===========================================================================*/
503 
504 #ifndef WCSLIB_TAB
505 #define WCSLIB_TAB
506 
507 #ifdef __cplusplus
508 extern "C" {
509 #endif
510 
511 
512 extern const char *tab_errmsg[];
513 
515  TABERR_SUCCESS = 0, /* Success. */
516  TABERR_NULL_POINTER = 1, /* Null tabprm pointer passed. */
517  TABERR_MEMORY = 2, /* Memory allocation failed. */
518  TABERR_BAD_PARAMS = 3, /* Invalid tabular parameters. */
519  TABERR_BAD_X = 4, /* One or more of the x coordinates were
520  invalid. */
521  TABERR_BAD_WORLD = 5 /* One or more of the world coordinates were
522  invalid. */
523 };
524 
525 struct tabprm {
526  /* Initialization flag (see the prologue above). */
527  /*------------------------------------------------------------------------*/
528  int flag; /* Set to zero to force initialization. */
529 
530  /* Parameters to be provided (see the prologue above). */
531  /*------------------------------------------------------------------------*/
532  int M; /* Number of tabular coordinate axes. */
533  int *K; /* Vector of length M whose elements */
534  /* (K_1, K_2,... K_M) record the lengths of */
535  /* the axes of the coordinate array and of */
536  /* each indexing vector. */
537  int *map; /* Vector of length M usually such that */
538  /* map[m-1] == i-1 for coordinate array */
539  /* axis m and image axis i (see above). */
540  double *crval; /* Vector of length M containing the index */
541  /* value for the reference pixel for each */
542  /* of the tabular coordinate axes. */
543  double **index; /* Vector of pointers to M indexing vectors */
544  /* of lengths (K_1, K_2,... K_M). */
545  double *coord; /* (1+M)-dimensional tabular coordinate */
546  /* array (see above). */
547 
548  /* Information derived from the parameters supplied. */
549  /*------------------------------------------------------------------------*/
550  int nc; /* Number of coordinate vectors (of length */
551  /* M) in the coordinate array. */
552  int padding; /* (Dummy inserted for alignment purposes.) */
553  int *sense; /* Vector of M flags that indicate whether */
554  /* the Mth indexing vector is monotonic */
555  /* increasing, or else decreasing. */
556  int *p0; /* Vector of M indices. */
557  double *delta; /* Vector of M increments. */
558  double *extrema; /* (1+M)-dimensional array of coordinate */
559  /* extrema. */
560 
561  /* Error handling */
562  /*------------------------------------------------------------------------*/
563  struct wcserr *err;
564 
565  /* Private - the remainder are for memory management. */
566  /*------------------------------------------------------------------------*/
567  int m_flag, m_M, m_N;
568  int set_M;
569  int *m_K, *m_map;
570  double *m_crval, **m_index, **m_indxs, *m_coord;
571 };
572 
573 /* Size of the tabprm struct in int units, used by the Fortran wrappers. */
574 #define TABLEN (sizeof(struct tabprm)/sizeof(int))
575 
576 
577 int tabini(int alloc, int M, const int K[], struct tabprm *tab);
578 
579 int tabmem(struct tabprm *tab);
580 
581 int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst);
582 
583 int tabcmp(int cmp, double tol, const struct tabprm *tab1,
584  const struct tabprm *tab2, int *equal);
585 
586 int tabfree(struct tabprm *tab);
587 
588 int tabprt(const struct tabprm *tab);
589 
590 int tabset(struct tabprm *tab);
591 
592 int tabx2s(struct tabprm *tab, int ncoord, int nelem, const double x[],
593  double world[], int stat[]);
594 
595 int tabs2x(struct tabprm *tab, int ncoord, int nelem, const double world[],
596  double x[], int stat[]);
597 
598 
599 /* Deprecated. */
600 #define tabini_errmsg tab_errmsg
601 #define tabcpy_errmsg tab_errmsg
602 #define tabfree_errmsg tab_errmsg
603 #define tabprt_errmsg tab_errmsg
604 #define tabset_errmsg tab_errmsg
605 #define tabx2s_errmsg tab_errmsg
606 #define tabs2x_errmsg tab_errmsg
607 
608 #ifdef __cplusplus
609 }
610 #endif
611 
612 #endif /* WCSLIB_TAB */
int tabfree(struct tabprm *tab)
Destructor for the tabprm struct.
Definition: tab.h:521
int set_M
Definition: tab.h:568
int tabini(int alloc, int M, const int K[], struct tabprm *tab)
Default constructor for the tabprm struct.
int tabset(struct tabprm *tab)
Setup routine for the tabprm struct.
Definition: tab.h:518
Error message handling.
Definition: wcserr.h:225
int m_flag
Definition: tab.h:567
double * m_crval
Definition: tab.h:570
int * map
Definition: tab.h:537
double * coord
Definition: tab.h:545
int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst)
Copy routine for the tabprm struct.
int * m_K
Definition: tab.h:569
int flag
Definition: tab.h:528
Definition: tab.h:515
const char * tab_errmsg[]
Status return messages.
double * delta
Definition: tab.h:557
Definition: tab.h:516
tab_errmsg_enum
Definition: tab.h:514
double ** m_index
Definition: tab.h:570
int tabprt(const struct tabprm *tab)
Print routine for the tabprm struct.
Definition: tab.h:517
int m_N
Definition: tab.h:567
int * m_map
Definition: tab.h:569
Definition: tab.h:519
double ** index
Definition: tab.h:543
double ** m_indxs
Definition: tab.h:570
int tabx2s(struct tabprm *tab, int ncoord, int nelem, const double x[], double world[], int stat[])
Pixel-to-world transformation.
int * sense
Definition: tab.h:553
int tabmem(struct tabprm *tab)
Acquire tabular memory.
Tabular transformation parameters.
Definition: tab.h:525
double * m_coord
Definition: tab.h:570
double * extrema
Definition: tab.h:558
int * K
Definition: tab.h:533
int padding
Definition: tab.h:552
struct wcserr * err
Definition: tab.h:563
int M
Definition: tab.h:532
double * crval
Definition: tab.h:540
int tabs2x(struct tabprm *tab, int ncoord, int nelem, const double world[], double x[], int stat[])
World-to-pixel transformation.
int * p0
Definition: tab.h:556
int tabcmp(int cmp, double tol, const struct tabprm *tab1, const struct tabprm *tab2, int *equal)
Compare two tabprm structs for equality.
int m_M
Definition: tab.h:567
int nc
Definition: tab.h:550