| File: | src/unrrdu/aabplot.c |
| Location: | line 207, column 3 |
| Description: | Potential leak of memory pointed to by 'line' |
| 1 | /* | |||
| 2 | Teem: Tools to process and visualize scientific data and images . | |||
| 3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago | |||
| 4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann | |||
| 5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah | |||
| 6 | ||||
| 7 | This library is free software; you can redistribute it and/or | |||
| 8 | modify it under the terms of the GNU Lesser General Public License | |||
| 9 | (LGPL) as published by the Free Software Foundation; either | |||
| 10 | version 2.1 of the License, or (at your option) any later version. | |||
| 11 | The terms of redistributing and/or modifying this software also | |||
| 12 | include exceptions to the LGPL that facilitate static linking. | |||
| 13 | ||||
| 14 | This library is distributed in the hope that it will be useful, | |||
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 17 | Lesser General Public License for more details. | |||
| 18 | ||||
| 19 | You should have received a copy of the GNU Lesser General Public License | |||
| 20 | along with this library; if not, write to Free Software Foundation, Inc., | |||
| 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 22 | */ | |||
| 23 | ||||
| 24 | #include "unrrdu.h" | |||
| 25 | #include "privateUnrrdu.h" | |||
| 26 | ||||
| 27 | #define INFO"Draws ASCII-art box plots" "Draws ASCII-art box plots" | |||
| 28 | static const char *_unrrdu_aabplotInfoL = | |||
| 29 | (INFO"Draws ASCII-art box plots" | |||
| 30 | ". Because why not.\n " | |||
| 31 | "* (uses nrrd, but no Nrrd implements this functionality)"); | |||
| 32 | ||||
| 33 | int | |||
| 34 | unrrdu_aabplotMain(int argc, const char **argv, const char *me, | |||
| 35 | hestParm *hparm) { | |||
| 36 | /* these are stock for unrrdu */ | |||
| 37 | hestOpt *opt = NULL((void*)0); | |||
| 38 | airArray *mop; | |||
| 39 | int pret; | |||
| 40 | char *err; | |||
| 41 | /* these are specific to this command */ | |||
| 42 | int medshow, rshow; | |||
| 43 | Nrrd *_nin, *nin, *_nsingle, *nsingle; | |||
| 44 | unsigned int plen; | |||
| 45 | double vrange[2], *single; | |||
| 46 | ||||
| 47 | hestOptAdd(&opt, "l", "len", airTypeUInt, 1, 1, &plen, "78", | |||
| 48 | "number of characters in box plot"); | |||
| 49 | hestOptAdd(&opt, "r", "min max", airTypeDouble, 2, 2, vrange, "0 100", | |||
| 50 | "values to use as absolute min and max (unfortunately " | |||
| 51 | "has to be same for all scanlines (rows)."); | |||
| 52 | hestOptAdd(&opt, "rs", "show", airTypeBool, 1, 1, &rshow, "false", | |||
| 53 | "show range above plots"); | |||
| 54 | hestOptAdd(&opt, "ms", "show", airTypeBool, 1, 1, &medshow, "false", | |||
| 55 | "print the median value"); | |||
| 56 | OPT_ADD_NIN(_nin, "input nrrd")hestOptAdd(&opt, "i,input", "nin", airTypeOther, 1, 1, & (_nin), "-", "input nrrd", ((void*)0), ((void*)0), nrrdHestNrrd ); | |||
| 57 | hestOptAdd(&opt, "s", "single", airTypeOther, 1, 1, &_nsingle, "", | |||
| 58 | "if given a 1D nrrd here that matches the number of " | |||
| 59 | "rows in the \"-i\" input, interpret it as a list of values " | |||
| 60 | "that should be indicated with \"X\"s in the plots.", | |||
| 61 | NULL((void*)0), NULL((void*)0), nrrdHestNrrd); | |||
| 62 | ||||
| 63 | mop = airMopNew(); | |||
| 64 | airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); | |||
| 65 | USAGE(_unrrdu_aabplotInfoL)if (!argc) { hestInfo(__stdoutp, me, (_unrrdu_aabplotInfoL), hparm ); hestUsage(__stdoutp, opt, me, hparm); hestGlossary(__stdoutp , opt, hparm); airMopError(mop); return 0; }; | |||
| 66 | PARSE()if ((pret=hestParse(opt, argc, argv, &err, hparm))) { if ( 1 == pret || 2 == pret) { if (!(getenv("UNRRDU_QUIET_QUIT") && airEndsWith(err, "[nrrd] _nrrdRead: immediately hit EOF" "\n" ))) { fprintf(__stderrp, "%s: %s\n", me, err); free(err); hestUsage (__stderrp, opt, me, hparm); hestGlossary(__stderrp, opt, hparm ); } airMopError(mop); return 1; } else { exit(1); } }; | |||
| 67 | airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); | |||
| 68 | ||||
| 69 | if (!( 2 == _nin->dim || 1 == _nin->dim )) { | |||
| ||||
| 70 | fprintf(stderr__stderrp, "%s: need 1-D or 2-D array\n", me); | |||
| 71 | airMopError(mop); | |||
| 72 | return 1; | |||
| 73 | } | |||
| 74 | nin = nrrdNew(); | |||
| 75 | airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); | |||
| 76 | if (nrrdConvert(nin, _nin, nrrdTypeDouble)) { | |||
| 77 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); | |||
| 78 | fprintf(stderr__stderrp, "%s: error converting \"-s\" input:\n%s", me, err); | |||
| 79 | airMopError(mop); | |||
| 80 | return 1; | |||
| 81 | } | |||
| 82 | if (1 == nin->dim) { | |||
| 83 | if (nrrdAxesInsert(nin, nin, 1)) { | |||
| 84 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); | |||
| 85 | fprintf(stderr__stderrp, "%s: error making 2-D from 1-D:\n%s", me, err); | |||
| 86 | airMopError(mop); | |||
| 87 | return 1; | |||
| 88 | } | |||
| 89 | } | |||
| 90 | if (_nsingle) { | |||
| 91 | if (nrrdElementNumber(_nsingle) != nin->axis[1].size) { | |||
| 92 | fprintf(stderr__stderrp, "%s: \"-s\" input doesn't match size of \"-i\" input", | |||
| 93 | me); | |||
| 94 | airMopError(mop); | |||
| 95 | return 1; | |||
| 96 | } | |||
| 97 | nsingle = nrrdNew(); | |||
| 98 | airMopAdd(mop, nsingle, (airMopper)nrrdNuke, airMopAlways); | |||
| 99 | if (nrrdConvert(nsingle, _nsingle, nrrdTypeDouble)) { | |||
| 100 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); | |||
| 101 | fprintf(stderr__stderrp, "%s: error converting \"-s\" input:\n%s", me, err); | |||
| 102 | airMopError(mop); | |||
| 103 | return 1; | |||
| 104 | } | |||
| 105 | single = (double*)nsingle->data; | |||
| 106 | } else { | |||
| 107 | nsingle = NULL((void*)0); | |||
| 108 | single = NULL((void*)0); | |||
| 109 | } | |||
| 110 | ||||
| 111 | { | |||
| 112 | #define PTNUM5 5 | |||
| 113 | double *in, *buff, ptile[PTNUM5]={5,25,50,75,95}; | |||
| 114 | unsigned int xi, yi, pi, ti, sx, sy, pti[PTNUM5]; | |||
| 115 | char *line, rbuff[128]; | |||
| 116 | Nrrd *nbuff; | |||
| 117 | ||||
| 118 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); | |||
| 119 | sy = AIR_CAST(unsigned int, nin->axis[1].size)((unsigned int)(nin->axis[1].size)); | |||
| 120 | nbuff = nrrdNew(); | |||
| 121 | airMopAdd(mop, nbuff, (airMopper)nrrdNuke, airMopAlways); | |||
| 122 | if (nrrdSlice(nbuff, nin, 1, 0)) { | |||
| 123 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); | |||
| 124 | fprintf(stderr__stderrp, "%s: error making buffer:\n%s", me, err); | |||
| 125 | airMopError(mop); | |||
| 126 | return 1; | |||
| 127 | } | |||
| 128 | line = calloc(plen+1, sizeof(char)); | |||
| 129 | in = (double*)nin->data; | |||
| 130 | buff = (double*)nbuff->data; | |||
| 131 | ||||
| 132 | if (rshow) { | |||
| 133 | for (pi=0; pi<plen; pi++) { | |||
| 134 | line[pi] = ' '; | |||
| 135 | } | |||
| 136 | sprintf(rbuff, "|<-- %g", vrange[0])__builtin___sprintf_chk (rbuff, 0, __builtin_object_size (rbuff , 2 > 1 ? 1 : 0), "|<-- %g", vrange[0]); | |||
| 137 | memcpy(line, rbuff, strlen(rbuff))__builtin___memcpy_chk (line, rbuff, strlen(rbuff), __builtin_object_size (line, 0)); | |||
| 138 | sprintf(rbuff, "%g -->|", vrange[1])__builtin___sprintf_chk (rbuff, 0, __builtin_object_size (rbuff , 2 > 1 ? 1 : 0), "%g -->|", vrange[1]); | |||
| 139 | memcpy(line + plen - strlen(rbuff), rbuff, strlen(rbuff))__builtin___memcpy_chk (line + plen - strlen(rbuff), rbuff, strlen (rbuff), __builtin_object_size (line + plen - strlen(rbuff), 0 )); | |||
| 140 | printf("%s", line); | |||
| 141 | if (medshow) { | |||
| 142 | printf(" median:"); | |||
| 143 | } | |||
| 144 | printf("\n"); | |||
| 145 | } | |||
| 146 | for (yi=0; yi<sy; yi++) { | |||
| 147 | for (xi=0; xi<sx; xi++) { | |||
| 148 | buff[xi] = in[xi + sx*yi]; | |||
| 149 | } | |||
| 150 | qsort(buff, sx, sizeof(double), nrrdValCompare[nrrdTypeDouble]); | |||
| 151 | for (ti=0; ti<PTNUM5; ti++) { | |||
| 152 | pti[ti] = airIndexClamp(vrange[0], | |||
| 153 | buff[airIndexClamp(0, ptile[ti], 100, sx)], | |||
| 154 | vrange[1], plen); | |||
| 155 | /* | |||
| 156 | fprintf(stderr, "ti %u (%g) -> buff[%u] = %g -> %u\n", ti, | |||
| 157 | ptile[ti], airIndexClamp(0, ptile[ti], 100, sx), | |||
| 158 | buff[airIndexClamp(0, ptile[ti], 100, sx)], pti[ti]); | |||
| 159 | */ | |||
| 160 | } | |||
| 161 | for (pi=0; pi<plen; pi++) { | |||
| 162 | line[pi] = pi % 2 ? ' ' : '.'; | |||
| 163 | } | |||
| 164 | for (pi=pti[0]; pi<=pti[4]; pi++) { | |||
| 165 | line[pi] = '-'; | |||
| 166 | } | |||
| 167 | for (pi=pti[1]; pi<=pti[3]; pi++) { | |||
| 168 | line[pi] = '='; | |||
| 169 | } | |||
| 170 | line[pti[2]]='m'; | |||
| 171 | if (pti[2] > 0) { | |||
| 172 | line[pti[2]-1]='<'; | |||
| 173 | } | |||
| 174 | if (pti[2] < plen-1) { | |||
| 175 | line[pti[2]+1]='>'; | |||
| 176 | } | |||
| 177 | if (single) { | |||
| 178 | line[airIndexClamp(vrange[0], single[yi], vrange[1], plen)]='X'; | |||
| 179 | } | |||
| 180 | printf("%s", line); | |||
| 181 | if (medshow) { | |||
| 182 | printf(" %g", buff[airIndexClamp(0, 50, 100, sx)]); | |||
| 183 | } | |||
| 184 | printf("\n"); | |||
| 185 | #if 0 | |||
| 186 | unsigned int ltt = (unsigned int)(-1); | |||
| 187 | /* printf("["); */ | |||
| 188 | for (pi=0; pi<plen; pi++) { | |||
| 189 | for (tt=0; tt<PTNUM5 && pti[tt] < pi; tt++) { | |||
| 190 | /* | |||
| 191 | fprintf(stderr, "(pi %u < pti[%u]==%u)", pi, tt, pti[tt]); | |||
| 192 | */ | |||
| 193 | } | |||
| 194 | /* fprintf(stderr, " --> tt=%u\n", tt); */ | |||
| 195 | if (2 == ltt && 3 == tt) { | |||
| 196 | printf("M"); | |||
| 197 | } else { | |||
| 198 | printf("%c", cc[tt]); | |||
| 199 | } | |||
| 200 | ltt = tt; | |||
| 201 | } | |||
| 202 | /* printf("]\n"); */ | |||
| 203 | printf("\n"); | |||
| 204 | #endif | |||
| 205 | } | |||
| 206 | } | |||
| 207 | airMopOkay(mop); | |||
| ||||
| 208 | return 0; | |||
| 209 | } | |||
| 210 | ||||
| 211 | UNRRDU_CMD_HIDE(aabplot, INFO)unrrduCmd unrrdu_aabplotCmd = { "aabplot", "Draws ASCII-art box plots" , unrrdu_aabplotMain, 1 }; |