/* ================================================================== FILE: "/home/joze/pub/zimg/zimg/cmdln.c" LAST MODIFIED: "Sa, 27 Aug 2005 14:44:08 CEST (joze)" (C) 1999 - 2003 by Johannes Zellner johannes@zellner.org $Id: cmdln.c,v 1.63 2005/08/27 12:46:20 joze Exp $ --- Copyright (c) 1999 - 2003, Johannes Zellner All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Johannes Zellner nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================== */ #include "zimg_priv.h" #ifdef HAVE_GETOPT_LONG # include #else # include "getopt/getopt.h" #endif enum { CMDLN_L_INT = 1002, CMDLN_CHAR = 1003, CMDLN_SHORT = 1004, CMDLN_INT = 1005, CMDLN_U_L_INT = 1006, CMDLN_COMPLEX_FLOAT = 1007, CMDLN_COMPLEX_DOUBLE = 1008, CMDLN_SWAP = 1010, CMDLN_DIFFERENTIATE = 1011, CMDLN_SMOOTH = 1012, CMDLN_ABSOLUTE = 1013, CMDLN_RELATIVE = 1014, CMDLN_RED = 1020, CMDLN_BLUE = 1021, CMDLN_GRAY = 1022, CMDLN_STATISTICS = 1040, CMDLN_BIGENDIAN = 1050, CMDLN_LITTLEENDIAN = 1051, CMDLN_INTERLACE = 1060, CMDLN_DUMP_COLORMAP = 1070, CMDLN_CBOX_FORMAT = 1071, CMDLN_CBOX_LABEL = 1072, CMDLN_LEGEND = 1085, CMDLN_VLABEL = 1090, CMDLN_LINE = 1095, CMDLN_RLINE = 1096, CMDLN_CONTOURS = 1100, CMDLN_OPTIONS = 1110, CMDLN_FILTER = 1111, CMDLN_PPM = 1112, CMDLN_PGM = 1113, CMDLN_NONE = 8000 }; int complex_switch(const char* oarg) { int len = strlen(oarg); if (!strncmp("abs", oarg, len) || !strncmp("length", oarg, len)) return COMPLEX_ACTION_ABS; else if (!strncmp("phase", oarg, len)) return COMPLEX_ACTION_PHASE; else if (!strncmp("real", oarg, len)) return COMPLEX_ACTION_REAL; else if (!strncmp("imaginary", oarg, len)) return COMPLEX_ACTION_IMAG; else { fprintf(stderr, "bad value `%s' for complex switch\n", oarg); exit(1); } } void range(zimg_t* z, const char* oarg, const char* desc, enum TRANSFORM_TYPE minmax_TT, enum TRANSFORM_TYPE min_TT, enum TRANSFORM_TYPE max_TT) { double min = 0; double max = 100; if (strchr(oarg, ',')) { int n = sscanf(oarg, "%lf,%lf", &min, &max); switch (n) { case 2: TRANS(z).type = minmax_TT; break; case 1: TRANS(z).type = min_TT; break; case 0: if (1 == sscanf(oarg, ",%lf", &max)) { TRANS(z).type = max_TT; } else { fprintf(stderr, "** should be: --%s=,\n", desc); exit(1); } break; } } else if (sscanf(oarg, "%lf-%lf", &min, &max) != 2) { fprintf(stderr, "** should be: --%s=-\n", desc); exit(1); } else { TRANS(z).type = minmax_TT; } if (minmax_TT == TRANS(z).type && min > max) { /* swap */ TRANS(z).p1 = max; TRANS(z).p2 = min; } else { TRANS(z).p1 = min; TRANS(z).p2 = max; } if (minmax_TT == relative_TT) { TRANS(z).p1 *= 0.01; TRANS(z).p2 *= 0.01; } z->transform_valid++; } void parseCrange(zimg_t* z, const char* oarg, const char* desc) { int res = 0; double min = 0; double max = 100; z->crange.setMin = z->crange.setMax = 0; if (strchr(oarg, ',')) { int n = sscanf(oarg, "%lf,%lf", &min, &max); switch (n) { case 2: z->crange.setMin = z->crange.setMax = 1; z->crange.theMin = (min < max) ? min : max; z->crange.theMax = (max > min) ? max : min; if (min==max) { fprintf(stderr, "** in --%s=, cannot min==max\n", desc); exit(1); } break; case 1: z->crange.setMin = 1; z->crange.theMin = min; break; case 0: if (1 == sscanf(oarg, ",%lf", &max)) { z->crange.setMax = 1; z->crange.theMax = max; } else res = 1; break; } } else res = 1; if (res) { fprintf(stderr, "** should be: --%s=,\n", desc); exit(1); } } void zimg_get_color(const char* str, zimg_color_t* color) { char* end; long int red; long int green; long int blue; char buf[3]; int digit = 1; color->set = 1; if (!strcasecmp(str, "black")) { color->red = 0; color->green = 0; color->blue = 0; return; } else if (!strcasecmp(str, "white")) { color->red = 255; color->green = 255; color->blue = 255; return; } else if (!strcasecmp(str, "red")) { color->red = 255; color->green = 0; color->blue = 0; return; } else if (!strcasecmp(str, "green")) { color->red = 0; color->green = 255; color->blue = 0; return; } else if (!strcasecmp(str, "blue")) { color->red = 0; color->green = 0; color->blue = 255; return; } else if (!strcasecmp(str, "magenta")) { color->red = 255; color->green = 0; color->blue = 255; } else if (!strcasecmp(str, "cyan")) { color->red = 0; color->green = 255; color->blue = 255; return; } else if (!strcasecmp(str, "yellow")) { color->red = 255; color->green = 255; color->blue = 0; return; } else if (3 == strlen(str)) { digit = 1; } else if (6 == strlen(str)) { digit = 2; } else { Fatal("color should be a 3 (xxx) or 6-digit (xxxxxx) hex, x = [0-9a-f]"); } buf[digit] = '\0'; /* terminate */ strncpy(buf, str, digit); red = strtol(buf, &end, 16); if (end == buf) Fatal("unable to parse hex color spec. (should be 00 - ff)"); strncpy(buf, str + digit, digit); green = strtol(buf, &end, 16); if (end == buf) Fatal("unable to parse hex color spec. (should be 00 - ff)"); strncpy(buf, str + 2 * digit, digit); blue = strtol(buf, &end, 16); if (end == buf) Fatal("unable to parse hex color spec. (should be 00 - ff)"); if (1 == digit) { red += (red << 4); green += (green << 4); blue += (blue << 4); } color->red = (unsigned char) red; color->green = (unsigned char) green; color->blue = (unsigned char) blue; } char* GetGeometry(const char* s, int* v1, int* v2) { char* endptr; char* endptr2; *v1 = strtol(s, &endptr, 10); if (endptr == s || !endptr || !(*endptr)) return (char*)0; /* failed to find first integer */ *v2 = strtol(endptr, &endptr2, 10); if (endptr2 == endptr || !endptr2) /* failed to convert second integer */ return (char*)0; return endptr2; /* success */ } #if 0 unsigned char GetPositiveIntegerPair(const char* s, int* v1, int* v2) { char* endptr; *v1 = strtol(s, &endptr, 10); if (endptr == s) return 1; /* failed to find at least one integer */ *v2 = *v1; if (endptr && *endptr && *(++endptr)) { char* endptr2; *v2 = strtol(endptr, &endptr2, 10); if (endptr2 == endptr) *v2 = *v1; } if (*v1 <= 0 || *v2 <= 0) return 1; else return 0; } #endif unsigned char GetPositiveDoublePair(const char* s, double* v1, double* v2) { char* endptr; *v1 = strtod(s, &endptr); if (endptr == s) return 1; /* failed to find at least one integer */ *v2 = *v1; if (endptr && *endptr && *(++endptr)) { char* endptr2; *v2 = strtod(endptr, &endptr2); if (endptr2 == endptr) *v2 = *v1; } if (*v1 <= 0 || *v2 <= 0) return 1; else return 0; } void readcmdln(int argc, char* argv[], zimg_t* z, int* ifiles, char*** iname) { char* ptr; int c; static struct option long_options[] = { {"size", required_argument, 0, 'r'}, {"matrix", no_argument, 0, 'M'}, {"float", no_argument, 0, 'f'}, {"double", no_argument, 0, 'd'}, {"char", no_argument, 0, CMDLN_CHAR}, {"short", no_argument, 0, CMDLN_SHORT}, {"int", no_argument, 0, CMDLN_INT}, {"long-int", no_argument, 0, CMDLN_L_INT}, {"unsigned-char", no_argument, 0, 'c'}, {"unsigned-short", no_argument, 0, 's'}, {"unsigned-int", no_argument, 0, 'i'}, {"unsigned-long-int", no_argument, 0, CMDLN_U_L_INT}, {"complex-float", optional_argument, 0, CMDLN_COMPLEX_FLOAT}, {"complex-double", optional_argument, 0, CMDLN_COMPLEX_DOUBLE}, {"pattern", required_argument, 0, 'p'}, {"column", optional_argument, 0, 'n'}, {"skip", optional_argument, 0, 'k'}, #ifdef HAVE_REGEX_H {"options", required_argument, 0, CMDLN_OPTIONS}, #endif #ifdef HAVE_POPEN {"input-filter", required_argument, 0, CMDLN_FILTER}, #endif {"swap", no_argument, 0, CMDLN_SWAP}, {"big-endian", no_argument, 0, CMDLN_BIGENDIAN}, {"little-endian", no_argument, 0, CMDLN_LITTLEENDIAN}, {"differentiate", no_argument, 0, CMDLN_DIFFERENTIATE}, {"curvature", no_argument, 0, 'u'}, {"smooth", optional_argument, 0, CMDLN_SMOOTH}, {"logarithmic", optional_argument, 0, 'l'}, {"fabs", no_argument, 0, 'a'}, {"absolute", required_argument, 0, CMDLN_ABSOLUTE}, {"relative", required_argument, 0, CMDLN_RELATIVE}, {"crange", required_argument, 0, 'z'}, {"no-data", optional_argument, 0, 'N'}, {"nda", optional_argument, 0, 'N'}, /* alias */ #if defined HAVE_DLSYM || defined HAVE_SHL_LOAD {"expr", required_argument, 0, 'e'}, {"expr-source", required_argument, 0, 'R'}, {"expr-object", required_argument, 0, 'O'}, #endif /**/ {"red", no_argument, 0, CMDLN_RED}, {"blue", no_argument, 0, CMDLN_BLUE}, {"grey", no_argument, 0, CMDLN_GRAY}, {"gray", no_argument, 0, CMDLN_GRAY}, {"invert", no_argument, 0, 'I'}, {"interlace", no_argument, 0, CMDLN_INTERLACE}, #ifdef GD_JPEG_VERSION {"jpeg", optional_argument, 0, 'j'}, #endif #if defined(GD_HAS_PNG) && defined (GD_HAS_GIF) {"gif", no_argument, 0, 'g'}, #endif {"ppmorpgm", no_argument, 0, 'P'}, {"ppm", no_argument, 0, CMDLN_PPM}, {"pgm", no_argument, 0, CMDLN_PGM}, {"xor", optional_argument, 0, 'x'}, {"colormap", optional_argument, 0, 'm'}, {"dump-colormap", no_argument, 0, CMDLN_DUMP_COLORMAP}, {"colorbox", optional_argument, 0, 'b'}, {"cbox", optional_argument, 0, 'b'}, {"cbox-fmt", optional_argument, 0, CMDLN_CBOX_FORMAT}, {"cbox-format", optional_argument, 0, CMDLN_CBOX_FORMAT}, {"cbox-label", optional_argument, 0, CMDLN_CBOX_LABEL}, {"output", required_argument, 0, 'o'}, #if 0 /* TODO: reimplement binning */ {"bin", required_argument, 0, 'B'}, #endif {"scale", required_argument, 0, 'S'}, {"crop", optional_argument, 0, 'C'}, {"align", required_argument, 0, 'A'}, #if 0 /* TODO: see below and zimg.h / misc.c */ {"extend", required_argument, 0, 'E'}, #endif {"contours", required_argument, 0, CMDLN_CONTOURS}, {"vlabel", required_argument, 0, CMDLN_VLABEL}, {"label", required_argument, 0, 't'}, {"font", required_argument, 0, 'F'}, {"textcolor", required_argument, 0, 'T'}, {"line", required_argument, 0, CMDLN_LINE}, {"rline", required_argument, 0, CMDLN_RLINE}, {"legend", optional_argument, 0, CMDLN_LEGEND}, {"license", no_argument, 0, 'L'}, {"version", no_argument, 0, 'V'}, {"debug", no_argument, 0, 'D'}, {"verbose", no_argument, 0, 'v'}, {"statistics", optional_argument, 0, CMDLN_STATISTICS}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} /* getopt () relies on this ! */ }; #if 0 for (c = 0; c < argc; c++) { fprintf(stderr, "(readcmdln) argv[%d] = |%s|\n", c, argv[c]); } #endif if (z->transform_valid + argc >= z->transform_allocated) { z->transform_allocated += argc > TRANSFORM_CHUNK_SIZE ? argc : TRANSFORM_CHUNK_SIZE; z->transform = (transform_t*) realloc(z->transform, sizeof (transform_t) * z->transform_allocated); } optind = 0; /* reset */ /* --- (command line arguments) --- */ while (1) { int option_index = 0; c = getopt_long (argc, argv, "ab::cde:fghij::k::l::m::n::o:p:r:st:uvx::A:C::DE:F:IMN::O:PR:S:VLT:z:", long_options, &option_index); if (c == -1) break; switch (c) { case CMDLN_ABSOLUTE: range(z, optarg, "absolute", absolute_TT, absolute_min_TT, absolute_max_TT); break; case CMDLN_RELATIVE: range(z, optarg, "relative", relative_TT, relative_min_TT, relative_max_TT); break; case 'z': parseCrange(z, optarg, "crange"); break; case 'N': if (optarg) { if (1 == sscanf(optarg, "%lf", &(z->nda))) { z->nda_specified = 1; } else if (1 == sscanf(optarg, "@%lf", &(z->nda_thres))) { if (z->nda_thres > 0 && z->nda_thres <= 1.) { /* do nothing, just accept this value */ } else if (z->nda_thres > 1. && z->nda_thres <= 100.) { z->nda_thres /= 100.; } else { Fatal("should be -N @ (where 0 < <= 100)"); } } ptr = strchr(optarg, ','); if (ptr && ++ptr && *ptr) zimg_get_color(ptr, &(z->nda_color)); } if (!z->nda_color.set) { zimg_get_color("white", &(z->nda_color)); } break; #if defined HAVE_DLSYM || defined HAVE_SHL_LOAD case 'e': if (z->expr) free(z->expr); z->expr = strdup(optarg); break; case 'R': if (z->expr_source) free(z->expr_source); z->expr_source = strdup(optarg); break; case 'O': if (z->expr_object) free(z->expr_object); z->expr_object = strdup(optarg); break; #endif case 'r': { char* endptr; z->data.x = strtol(optarg, &endptr, 10); if (endptr == optarg) Fatal("should be --size=x"); if (endptr && (*endptr == 'x' || *endptr == ',')) { char* endptr2; endptr++; if (*endptr) { z->data.y = strtol(endptr, &endptr2, 10); if (endptr2 == endptr) z->data.y = z->data.x; } } else { z->data.y = z->data.x; } if ((z->data.len = z->data.x * z->data.y) <= 0) { Fatal("dimensions must be strictly positive"); } } break; case 'M': z->inputformat = MATRIX_FORMAT; break; case CMDLN_DIFFERENTIATE: TRANS(z).type = differentiate_TT; z->transform_valid++; break; case 'u': TRANS(z).type = curvature_TT; z->transform_valid++; break; case CMDLN_SMOOTH: { if (optarg) { double sigma; if (sscanf (optarg, "%lf", &sigma) != 1 || sigma <= 0) { Fatal("should be --smooth[=]"); } TRANS(z).p1 = sigma; } else { TRANS(z).p1 = 3.0; /* default: 3.0 * sigma */ } TRANS(z).type = smooth_TT; z->transform_valid++; } break; case 'a': TRANS(z).type = fabs_TT; z->transform_valid++; break; case 'I': z->color ^= INVERT_MAP; break; case CMDLN_INTERLACE: z->interlace = (TRUE == z->interlace) ? FALSE : TRUE; break; #if defined(GD_HAS_PNG) && defined (GD_HAS_GIF) case 'g': z->imformat = IMFORMAT_GIF; break; #endif #ifdef GD_JPEG_VERSION case 'j': z->imformat = IMFORMAT_JPG; if (optarg) { int itmp; if (sscanf (optarg, "%d", &itmp) != 1 || itmp < 0 || itmp > 100) { Fatal("should be --jpeg[=0 - 100]"); } z->jpeg_quality = itmp; } else { z->jpeg_quality = -1; /* default value of the jpeg quality */ } break; #endif case 'P': z->imformat = IMFORMAT_PPMorPGM; /* later: if the palette is gray, then auto change imformat to * IMFORMAT_PGM, otherwise to IMFORMAT_PPM */ break; case CMDLN_PPM: z->imformat = IMFORMAT_PPM; break; case CMDLN_PGM: z->imformat = IMFORMAT_PGM; break; case 'x': if (optarg) { zimg_get_color(optarg, &(z->xor_color)); } else { zimg_get_color("white", &(z->xor_color)); } z->color ^= XOR_MAP; break; case CMDLN_RED: z->color &= (INVERT_MAP | XOR_MAP | REDMAP); z->color ^= REDMAP; break; case CMDLN_BLUE: z->color &= (INVERT_MAP | XOR_MAP | BLUEMAP); z->color ^= BLUEMAP; break; case CMDLN_GRAY: z->color &= (INVERT_MAP | XOR_MAP | GRAYMAP); z->color ^= GRAYMAP; break; case 'm': /* restore std colormap */ z->color &= (INVERT_MAP | XOR_MAP); if (optarg) { int itmp; int vtmp[3]; if ((itmp = sscanf(optarg, "%i,%i,%i", vtmp, vtmp + 1, vtmp + 2))) { int i; if (itmp < 2) vtmp[1] = vtmp[0]; if (itmp < 3) vtmp[2] = vtmp[1]; for (i = 0; i < 3; i++) z->rgbformulae[i] = vtmp[i]; z->color |= RGBMAP; } else { if (z->colormapfile) free(z->colormapfile); z->colormapfile = strdup(optarg); if (!z->colormapfile) { perror("readcmdln->z->colormapfile"); exit(2); } } } break; case 'b': /* toggle */ z->colorbox.show = 1; if (optarg) { char* endptr; z->colorbox.levels = strtol(optarg, &endptr, 0); if (endptr == optarg) z->colorbox.levels = -1; /* auto levels */ } break; case CMDLN_CBOX_FORMAT: if (z->colorbox.fmt) free(z->colorbox.fmt); if (optarg) { if ('%' != *optarg) Fatal("expected a sprintf format starting with '%'"); z->colorbox.fmt = strdup(optarg); z->colorbox.show = 1; /* turn on colorbox implicitely */ } break; case CMDLN_CBOX_LABEL: if (z->colorbox.label) free(z->colorbox.label); if (optarg) { z->colorbox.label = strdup(optarg); z->colorbox.show = 1; /* turn on colorbox implicitely */ } break; case CMDLN_DUMP_COLORMAP: z->dump_colormap = 1; break; case 'l': { if (optarg) { double fact; if (sscanf (optarg, "%lf", &fact) != 1 || fact <= 0) { Fatal("should be --log=[]"); } TRANS(z).p1 = fact; } else { TRANS(z).p1 = 1.0; /* default */ } TRANS(z).type = logarithmic_TT; z->transform_valid++; } break; case 'o': strcpy(z->oname, optarg); break; case CMDLN_CHAR: z->inputformat = CHAR_FORMAT; z->b_len = sizeof (signed char); break; case CMDLN_SHORT: z->inputformat = SHORT_FORMAT; z->b_len = sizeof (signed short); break; case CMDLN_INT: z->inputformat = INT_FORMAT; z->b_len = sizeof (signed int); break; case CMDLN_L_INT: z->inputformat = L_INT_FORMAT; z->b_len = sizeof (signed long int); break; case 'c': z->inputformat = U_CHAR_FORMAT; z->b_len = sizeof (unsigned char); break; case 's': z->inputformat = U_SHORT_FORMAT; z->b_len = sizeof (unsigned short); break; case 'i': z->inputformat = U_INT_FORMAT; z->b_len = sizeof (unsigned int); break; case CMDLN_U_L_INT: z->inputformat = U_L_INT_FORMAT; z->b_len = sizeof (unsigned long int); break; case CMDLN_COMPLEX_FLOAT: z->inputformat = COMPLEX_FLOAT_FORMAT; z->b_len = 2 * sizeof (float); if (optarg) { z->complex_action = complex_switch(optarg); } else { z->complex_action = COMPLEX_ACTION_ABS; } break; case CMDLN_COMPLEX_DOUBLE: z->inputformat = COMPLEX_DOUBLE_FORMAT; z->b_len = 2 * sizeof (double); if (optarg) { z->complex_action = complex_switch(optarg); } else { z->complex_action = COMPLEX_ACTION_ABS; } break; case 'f': z->inputformat = FLOAT_FORMAT; z->b_len = sizeof (float); break; case 'd': z->inputformat = DOUBLE_FORMAT; z->b_len = sizeof (double); break; case 'k': if (optarg) { if (sscanf(optarg, "%i", &(z->skip)) != 1) { Fatal("should be --skip[=]"); } } else { /* reset to the default */ z->skip = UNSET; } break; #ifdef HAVE_REGEX_H case CMDLN_OPTIONS: if (z->noptions + 1 < ZIMG_MAX_OPTIONS) { char* sep; char* optarg_cpy; if (strlen(optarg) < 4) Fatal("should be --options=/regexp/switches"); optarg_cpy = strdup(optarg); assert(optarg_cpy); sep = strchr(optarg_cpy + 1, *optarg_cpy); if (!sep) { Fatal("should be --options=/regexp/switches"); } else { int err; z->options[z->noptions].switches = strdup(sep + 1); assert(z->options[z->noptions].switches); *sep = '\0'; /* terminate */ err = regcomp(&(z->options[z->noptions].preg), optarg_cpy + 1, REG_EXTENDED); if (err) { size_t size = regerror(err, &(z->options[z->noptions].preg), (char*)0, 0); char* msg = (char*)malloc(sizeof (char) * size); regerror(err, &(z->options[z->noptions].preg), msg, size); Fatal(msg); } if (!strlen(z->options[z->noptions].switches)) { free(z->options[z->noptions].switches); regfree(&(z->options[z->noptions].preg)); Fatal("should be --options=/regexp/switches"); } } z->noptions++; } else { fprintf(stderr, "WARNING: maximum number of options exceeded (%d)\n", ZIMG_MAX_OPTIONS); } break; #endif #ifdef HAVE_POPEN case CMDLN_FILTER: if (z->filter) free(z->filter); z->filter = strdup(optarg); assert(z->filter); break; #endif case CMDLN_SWAP: z->swap = (TRUE == z->swap) ? FALSE : TRUE; break; case CMDLN_BIGENDIAN: #ifdef WORDS_BIGENDIAN z->swap = FALSE; #else z->swap = TRUE; #endif break; case CMDLN_LITTLEENDIAN: #ifdef WORDS_BIGENDIAN z->swap = TRUE; #else z->swap = FALSE; #endif break; case 'p': sprintf(z->pattern[z->nn_pattern++], "%s", optarg); break; case 'n': if (optarg) { int which; if (sscanf(optarg, "%i", &which) != 1 || --which < 0 || which >= 32) Fatal("should be --column[=] where 1 <= <= 32"); else z->column |= (1 << which); /* read this column */ } else { /* enable unformatted column data */ z->column = z->column ? 0 : ALL_COLUMNS; } break; case CMDLN_LEGEND: if (z->legend) free(z->legend); if (optarg) z->legend = strdup(optarg); break; case CMDLN_VLABEL: /* FALLTHRU */ case 't': { zimg_label_t* label = (zimg_label_t*) malloc(sizeof (zimg_label_t)); char* ptr; assert(label); ptr = GetGeometry(optarg, &(label->x), &(label->y)); if (!ptr) Fatal("should be: --label=[+-][+-],