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 }; |