| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #include "regmach.h" | 
| 2 |  |  |  |  |  |  | #include | 
| 3 |  |  |  |  |  |  | #include "imageri.h" | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | /*#define DEBUG*/ | 
| 6 |  |  |  |  |  |  | #ifdef DEBUG | 
| 7 |  |  |  |  |  |  | #define DBG(x) printf x | 
| 8 |  |  |  |  |  |  | #else | 
| 9 |  |  |  |  |  |  | #define DBG(x) | 
| 10 |  |  |  |  |  |  | #endif | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | static float MAX_EXP_ARG; /* = log(DBL_MAX); */ | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | /* these functions currently assume RGB images - there seems to be some | 
| 16 |  |  |  |  |  |  | support for other color spaces, but I can't tell how you find what | 
| 17 |  |  |  |  |  |  | space an image is using. | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | HSV conversions from pages 401-403 "Procedural Elements for Computer | 
| 20 |  |  |  |  |  |  | Graphics", 1985, ISBN 0-07-053534-5.  The algorithm presents to produce | 
| 21 |  |  |  |  |  |  | an HSV color calculates all components at once - I don't, so I've | 
| 22 |  |  |  |  |  |  | simiplified the algorithm to avoid unnecessary calculation (any errors | 
| 23 |  |  |  |  |  |  | (of which I had a few ;) are mine). | 
| 24 |  |  |  |  |  |  | */ | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | /* returns the value (brightness) of color from 0 to 1 */ | 
| 27 | 1 |  |  |  |  |  | static double hsv_value(i_color color) { | 
| 28 | 1 |  |  |  |  |  | return i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b) / 255.0; | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | /* returns the hue (color) of color from 0 to 360 */ | 
| 32 | 1 |  |  |  |  |  | static double hsv_hue(i_color color) { | 
| 33 |  |  |  |  |  |  | int val; | 
| 34 |  |  |  |  |  |  | int temp; | 
| 35 | 1 |  |  |  |  |  | temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b); | 
| 36 | 1 |  |  |  |  |  | val = i_max(color.rgb.r, i_max(color.rgb.g, color.rgb.b)); | 
| 37 | 1 | 50 |  |  |  |  | if (val == 0 || val==temp) { | 
|  |  | 50 |  |  |  |  |  | 
| 38 | 0 |  |  |  |  |  | return 0; | 
| 39 |  |  |  |  |  |  | } | 
| 40 |  |  |  |  |  |  | else { | 
| 41 | 1 |  |  |  |  |  | double cr = (val - color.rgb.r) / (double)(val - temp); | 
| 42 | 1 |  |  |  |  |  | double cg = (val - color.rgb.g) / (double)(val - temp); | 
| 43 | 1 |  |  |  |  |  | double cb = (val - color.rgb.b) / (double)(val - temp); | 
| 44 |  |  |  |  |  |  | double hue; | 
| 45 | 1 | 50 |  |  |  |  | if (color.rgb.r == val) { | 
| 46 | 1 |  |  |  |  |  | hue = cb-cg; | 
| 47 |  |  |  |  |  |  | } | 
| 48 | 0 | 0 |  |  |  |  | else if (color.rgb.g == val) { | 
| 49 | 0 |  |  |  |  |  | hue = 2.0 + cr-cb; | 
| 50 |  |  |  |  |  |  | } | 
| 51 |  |  |  |  |  |  | else { /* if (blue == val) */ | 
| 52 | 0 |  |  |  |  |  | hue = 4.0 + cg - cr; | 
| 53 |  |  |  |  |  |  | } | 
| 54 | 1 |  |  |  |  |  | hue *= 60.0; /* to degrees */ | 
| 55 | 1 | 50 |  |  |  |  | if (hue < 0) | 
| 56 | 0 |  |  |  |  |  | hue += 360; | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 1 |  |  |  |  |  | return hue; | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | /* return the saturation of color from 0 to 1 */ | 
| 63 | 2 |  |  |  |  |  | static double hsv_sat(i_color color) { | 
| 64 | 2 |  |  |  |  |  | int value = i_max(i_max(color.rgb.r, color.rgb.g), color.rgb.b); | 
| 65 | 2 | 50 |  |  |  |  | if (value == 0) { | 
| 66 | 0 |  |  |  |  |  | return 0; | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  | else { | 
| 69 | 2 |  |  |  |  |  | int temp = i_min(i_min(color.rgb.r, color.rgb.g), color.rgb.b); | 
| 70 | 2 |  |  |  |  |  | return (value - temp) / (double)value; | 
| 71 |  |  |  |  |  |  | } | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 90004 |  |  |  |  |  | static i_color make_hsv(double hue, double sat, double val, int alpha) { | 
| 75 |  |  |  |  |  |  | int i; | 
| 76 |  |  |  |  |  |  | i_color c; | 
| 77 | 450020 | 100 |  |  |  |  | for( i=0; i< MAXCHANNELS; i++) c.channel[i]=0; | 
| 78 |  |  |  |  |  |  | DBG(("hsv=%f %f %f\n", hue, sat, val)); | 
| 79 | 90004 | 100 |  |  |  |  | if (sat <= 0) { /* handle -ve in case someone supplies a bad value */ | 
| 80 |  |  |  |  |  |  | /* should this be * 256? */ | 
| 81 | 1 |  |  |  |  |  | c.rgb.r = c.rgb.g = c.rgb.b = 255 * val; | 
| 82 |  |  |  |  |  |  | } | 
| 83 |  |  |  |  |  |  | else { | 
| 84 |  |  |  |  |  |  | int i, m, n, k, v; | 
| 85 |  |  |  |  |  |  | double f; | 
| 86 |  |  |  |  |  |  |  | 
| 87 | 90003 | 50 |  |  |  |  | if (val < 0) val = 0; | 
| 88 | 90003 | 50 |  |  |  |  | if (val > 1) val = 1; | 
| 89 | 90003 | 50 |  |  |  |  | if (sat > 1) sat = 1; | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | /* I want to handle -360 <= hue < 720 so that the caller can | 
| 92 |  |  |  |  |  |  | fiddle with colour | 
| 93 |  |  |  |  |  |  | */ | 
| 94 | 90003 | 50 |  |  |  |  | if (hue >= 360) | 
| 95 | 0 |  |  |  |  |  | hue -= 360; | 
| 96 | 90003 | 100 |  |  |  |  | else if (hue < 0) | 
| 97 | 501 |  |  |  |  |  | hue += 360; | 
| 98 | 90003 |  |  |  |  |  | hue /= 60; | 
| 99 | 90003 |  |  |  |  |  | i = hue; /* floor */ | 
| 100 | 90003 |  |  |  |  |  | f = hue - i; | 
| 101 | 90003 |  |  |  |  |  | val *= 255; | 
| 102 | 90003 |  |  |  |  |  | m = val * (1.0 - sat); | 
| 103 | 90003 |  |  |  |  |  | n = val * (1.0 - sat * f); | 
| 104 | 90003 |  |  |  |  |  | k = val * (1.0 - sat * (1 - f)); | 
| 105 | 90003 |  |  |  |  |  | v = val; | 
| 106 | 90003 |  |  |  |  |  | switch (i) { | 
| 107 |  |  |  |  |  |  | case 0: | 
| 108 | 18075 |  |  |  |  |  | c.rgb.r = v; c.rgb.g = k; c.rgb.b = m; | 
| 109 | 18075 |  |  |  |  |  | break; | 
| 110 |  |  |  |  |  |  | case 1: | 
| 111 | 18045 |  |  |  |  |  | c.rgb.r = n; c.rgb.g = v; c.rgb.b = m; | 
| 112 | 18045 |  |  |  |  |  | break; | 
| 113 |  |  |  |  |  |  | case 2: | 
| 114 | 17912 |  |  |  |  |  | c.rgb.r = m; c.rgb.g = v; c.rgb.b = k; | 
| 115 | 17912 |  |  |  |  |  | break; | 
| 116 |  |  |  |  |  |  | case 3: | 
| 117 | 17830 |  |  |  |  |  | c.rgb.r = m; c.rgb.g = n; c.rgb.b = v; | 
| 118 | 17830 |  |  |  |  |  | break; | 
| 119 |  |  |  |  |  |  | case 4: | 
| 120 | 17743 |  |  |  |  |  | c.rgb.r = k; c.rgb.g = m; c.rgb.b = v; | 
| 121 | 17743 |  |  |  |  |  | break; | 
| 122 |  |  |  |  |  |  | case 5: | 
| 123 | 398 |  |  |  |  |  | c.rgb.r = v; c.rgb.g = m; c.rgb.b = n; | 
| 124 | 398 |  |  |  |  |  | break; | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  | } | 
| 127 | 90004 |  |  |  |  |  | c.rgba.a = alpha; | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 90004 |  |  |  |  |  | return c; | 
| 130 |  |  |  |  |  |  | } | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 91080 |  |  |  |  |  | static i_color make_rgb(int r, int g, int b, int a) { | 
| 133 |  |  |  |  |  |  | i_color c; | 
| 134 | 91080 | 50 |  |  |  |  | if (r < 0) | 
| 135 | 0 |  |  |  |  |  | r = 0; | 
| 136 | 91080 | 50 |  |  |  |  | if (r > 255) | 
| 137 | 0 |  |  |  |  |  | r = 255; | 
| 138 | 91080 |  |  |  |  |  | c.rgb.r = r; | 
| 139 | 91080 | 50 |  |  |  |  | if (g < 0) | 
| 140 | 0 |  |  |  |  |  | g = 0; | 
| 141 | 91080 | 50 |  |  |  |  | if (g > 255) | 
| 142 | 0 |  |  |  |  |  | g = 255; | 
| 143 | 91080 |  |  |  |  |  | c.rgb.g = g; | 
| 144 | 91080 | 50 |  |  |  |  | if (b < 0) | 
| 145 | 0 |  |  |  |  |  | b = 0; | 
| 146 | 91080 | 50 |  |  |  |  | if (b > 255) | 
| 147 | 0 |  |  |  |  |  | b = 255; | 
| 148 | 91080 |  |  |  |  |  | c.rgb.b = b; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 91080 |  |  |  |  |  | c.rgba.a = a; | 
| 151 |  |  |  |  |  |  |  | 
| 152 | 91080 |  |  |  |  |  | return c; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | /* greatly simplifies the code */ | 
| 156 |  |  |  |  |  |  | #define nout n_regs[codes->rout] | 
| 157 |  |  |  |  |  |  | #define na n_regs[codes->ra] | 
| 158 |  |  |  |  |  |  | #define nb n_regs[codes->rb] | 
| 159 |  |  |  |  |  |  | #define nc n_regs[codes->rc] | 
| 160 |  |  |  |  |  |  | #define nd n_regs[codes->rd] | 
| 161 |  |  |  |  |  |  | #define cout c_regs[codes->rout] | 
| 162 |  |  |  |  |  |  | #define ca c_regs[codes->ra] | 
| 163 |  |  |  |  |  |  | #define cb c_regs[codes->rb] | 
| 164 |  |  |  |  |  |  | #define cc c_regs[codes->rc] | 
| 165 |  |  |  |  |  |  | #define cd c_regs[codes->rd] | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | /* this is a pretty poor epsilon used for loosening up equality comparisons | 
| 168 |  |  |  |  |  |  | It isn't currently used for inequalities | 
| 169 |  |  |  |  |  |  | */ | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | #define n_epsilon(x, y) (fabs(x)+fabs(y))*0.001 | 
| 172 |  |  |  |  |  |  | static i_color bcol = {{ 0 }}; | 
| 173 |  |  |  |  |  |  |  | 
| 174 | 181082 |  |  |  |  |  | i_color i_rm_run(struct rm_op codes[], size_t code_count, | 
| 175 |  |  |  |  |  |  | double n_regs[],  size_t n_regs_count, | 
| 176 |  |  |  |  |  |  | i_color c_regs[], size_t c_regs_count, | 
| 177 |  |  |  |  |  |  | i_img *images[],  size_t image_count) { | 
| 178 |  |  |  |  |  |  | double dx, dy; | 
| 179 | 181082 |  |  |  |  |  | struct rm_op *codes_base = codes; | 
| 180 | 181082 |  |  |  |  |  | size_t count_base = code_count; | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | DBG(("rm_run(%p, %d)\n", codes, code_count)); | 
| 183 | 2076111 | 50 |  |  |  |  | while (code_count) { | 
| 184 |  |  |  |  |  |  | DBG((" rm_code %d\n", codes->code)); | 
| 185 | 2076111 |  |  |  |  |  | switch (codes->code) { | 
| 186 |  |  |  |  |  |  | case rbc_add: | 
| 187 | 273566 |  |  |  |  |  | nout = na + nb; | 
| 188 | 273566 |  |  |  |  |  | break; | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | case rbc_subtract: | 
| 191 | 212021 |  |  |  |  |  | nout = na - nb; | 
| 192 | 212021 |  |  |  |  |  | break; | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | case rbc_mult: | 
| 195 | 600114 |  |  |  |  |  | nout = na * nb; | 
| 196 | 600114 |  |  |  |  |  | break; | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | case rbc_div: | 
| 199 | 2500 | 50 |  |  |  |  | if (fabs(nb) < 1e-10) | 
| 200 | 0 |  |  |  |  |  | nout = 1e10; | 
| 201 |  |  |  |  |  |  | else | 
| 202 | 2500 |  |  |  |  |  | nout = na / nb; | 
| 203 | 2500 |  |  |  |  |  | break; | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | case rbc_mod: | 
| 206 | 149041 | 50 |  |  |  |  | if (fabs(nb) > 1e-10) { | 
| 207 | 149041 |  |  |  |  |  | nout = fmod(na, nb); | 
| 208 |  |  |  |  |  |  | } | 
| 209 |  |  |  |  |  |  | else { | 
| 210 | 0 |  |  |  |  |  | nout = 0; /* close enough ;) */ | 
| 211 |  |  |  |  |  |  | } | 
| 212 | 149041 |  |  |  |  |  | break; | 
| 213 |  |  |  |  |  |  |  | 
| 214 |  |  |  |  |  |  | case rbc_pow: | 
| 215 | 2 |  |  |  |  |  | nout = pow(na, nb); | 
| 216 | 2 |  |  |  |  |  | break; | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | case rbc_uminus: | 
| 219 | 1 |  |  |  |  |  | nout = -na; | 
| 220 | 1 |  |  |  |  |  | break; | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | case rbc_multp: | 
| 223 | 59041 |  |  |  |  |  | cout = make_rgb(ca.rgb.r * nb, ca.rgb.g * nb, ca.rgb.b * nb, 255); | 
| 224 | 59041 |  |  |  |  |  | break; | 
| 225 |  |  |  |  |  |  |  | 
| 226 |  |  |  |  |  |  | case rbc_addp: | 
| 227 | 29521 |  |  |  |  |  | cout = make_rgb(ca.rgb.r + cb.rgb.r, ca.rgb.g + cb.rgb.g, | 
| 228 | 59042 |  |  |  |  |  | ca.rgb.b + cb.rgb.b, 255); | 
| 229 | 29521 |  |  |  |  |  | break; | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | case rbc_subtractp: | 
| 232 | 1 |  |  |  |  |  | cout = make_rgb(ca.rgb.r - cb.rgb.r, ca.rgb.g - cb.rgb.g, | 
| 233 | 2 |  |  |  |  |  | ca.rgb.b - cb.rgb.b, 255); | 
| 234 | 1 |  |  |  |  |  | break; | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | case rbc_sin: | 
| 237 | 119521 |  |  |  |  |  | nout = sin(na); | 
| 238 | 119521 |  |  |  |  |  | break; | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | case rbc_cos: | 
| 241 | 1 |  |  |  |  |  | nout = cos(na); | 
| 242 | 1 |  |  |  |  |  | break; | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | case rbc_atan2: | 
| 245 | 90001 |  |  |  |  |  | nout = atan2(na, nb); | 
| 246 | 90001 |  |  |  |  |  | break; | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | case rbc_sqrt: | 
| 249 | 1 |  |  |  |  |  | nout = sqrt(na); | 
| 250 | 1 |  |  |  |  |  | break; | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | case rbc_distance: | 
| 253 | 90001 |  |  |  |  |  | dx = na-nc; | 
| 254 | 90001 |  |  |  |  |  | dy = nb-nd; | 
| 255 | 90001 |  |  |  |  |  | nout = sqrt(dx*dx+dy*dy); | 
| 256 | 90001 |  |  |  |  |  | break; | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | case rbc_getp1: | 
| 259 | 88574 |  |  |  |  |  | i_gpix(images[0], na, nb, c_regs+codes->rout); | 
| 260 | 88574 | 50 |  |  |  |  | if (images[0]->channels < 4) cout.rgba.a = 255; | 
| 261 | 88574 |  |  |  |  |  | break; | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | case rbc_getp2: | 
| 264 | 29520 |  |  |  |  |  | i_gpix(images[1], na, nb, c_regs+codes->rout); | 
| 265 | 29520 | 50 |  |  |  |  | if (images[1]->channels < 4) cout.rgba.a = 255; | 
| 266 | 29520 |  |  |  |  |  | break; | 
| 267 |  |  |  |  |  |  |  | 
| 268 |  |  |  |  |  |  | case rbc_getp3: | 
| 269 | 0 |  |  |  |  |  | i_gpix(images[2], na, nb, c_regs+codes->rout); | 
| 270 | 0 | 0 |  |  |  |  | if (images[2]->channels < 4) cout.rgba.a = 255; | 
| 271 | 0 |  |  |  |  |  | break; | 
| 272 |  |  |  |  |  |  |  | 
| 273 |  |  |  |  |  |  | case rbc_value: | 
| 274 | 1 |  |  |  |  |  | nout = hsv_value(ca); | 
| 275 | 1 |  |  |  |  |  | break; | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | case rbc_hue: | 
| 278 | 1 |  |  |  |  |  | nout = hsv_hue(ca); | 
| 279 | 1 |  |  |  |  |  | break; | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | case rbc_sat: | 
| 282 | 2 |  |  |  |  |  | nout = hsv_sat(ca); | 
| 283 | 2 |  |  |  |  |  | break; | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | case rbc_hsv: | 
| 286 | 90004 |  |  |  |  |  | cout = make_hsv(na, nb, nc, 255); | 
| 287 | 90004 |  |  |  |  |  | break; | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | case rbc_hsva: | 
| 290 | 0 |  |  |  |  |  | cout = make_hsv(na, nb, nc, nd); | 
| 291 | 0 |  |  |  |  |  | break; | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | case rbc_red: | 
| 294 | 6 |  |  |  |  |  | nout = ca.rgb.r; | 
| 295 | 6 |  |  |  |  |  | break; | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | case rbc_green: | 
| 298 | 6 |  |  |  |  |  | nout = ca.rgb.g; | 
| 299 | 6 |  |  |  |  |  | break; | 
| 300 |  |  |  |  |  |  |  | 
| 301 |  |  |  |  |  |  | case rbc_blue: | 
| 302 | 4 |  |  |  |  |  | nout = ca.rgb.b; | 
| 303 | 4 |  |  |  |  |  | break; | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | case rbc_alpha: | 
| 306 | 0 |  |  |  |  |  | nout = ca.rgba.a; | 
| 307 | 0 |  |  |  |  |  | break; | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | case rbc_rgb: | 
| 310 | 17 |  |  |  |  |  | cout = make_rgb(na, nb, nc, 255); | 
| 311 | 17 |  |  |  |  |  | break; | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | case rbc_rgba: | 
| 314 | 2500 |  |  |  |  |  | cout = make_rgb(na, nb, nc, nd); | 
| 315 | 2500 |  |  |  |  |  | break; | 
| 316 |  |  |  |  |  |  |  | 
| 317 |  |  |  |  |  |  | case rbc_int: | 
| 318 | 1 |  |  |  |  |  | nout = (int)(na); | 
| 319 | 1 |  |  |  |  |  | break; | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | case rbc_if: | 
| 322 | 2 | 100 |  |  |  |  | nout = na ? nb : nc; | 
| 323 | 2 |  |  |  |  |  | break; | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | case rbc_ifp: | 
| 326 | 1 | 50 |  |  |  |  | cout = na ? cb : cc; | 
| 327 | 1 |  |  |  |  |  | break; | 
| 328 |  |  |  |  |  |  |  | 
| 329 |  |  |  |  |  |  | case rbc_le: | 
| 330 | 1 | 50 |  |  |  |  | nout = na <= nb + n_epsilon(na,nb); | 
| 331 | 1 |  |  |  |  |  | break; | 
| 332 |  |  |  |  |  |  |  | 
| 333 |  |  |  |  |  |  | case rbc_lt: | 
| 334 | 1 | 50 |  |  |  |  | nout = na < nb; | 
| 335 | 1 |  |  |  |  |  | break; | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | case rbc_ge: | 
| 338 | 1 | 50 |  |  |  |  | nout = na >= nb - n_epsilon(na,nb); | 
| 339 | 1 |  |  |  |  |  | break; | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | case rbc_gt: | 
| 342 | 1 | 50 |  |  |  |  | nout = na > nb; | 
| 343 | 1 |  |  |  |  |  | break; | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | case rbc_eq: | 
| 346 | 1 | 50 |  |  |  |  | nout = fabs(na-nb) <= n_epsilon(na,nb); | 
| 347 | 1 |  |  |  |  |  | break; | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | case rbc_ne: | 
| 350 | 1 | 50 |  |  |  |  | nout = fabs(na-nb) > n_epsilon(na,nb); | 
| 351 | 1 |  |  |  |  |  | break; | 
| 352 |  |  |  |  |  |  |  | 
| 353 |  |  |  |  |  |  | case rbc_and: | 
| 354 | 1 | 50 |  |  |  |  | nout = na && nb; | 
|  |  | 50 |  |  |  |  |  | 
| 355 | 1 |  |  |  |  |  | break; | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | case rbc_or: | 
| 358 | 1 | 50 |  |  |  |  | nout = na || nb; | 
|  |  | 0 |  |  |  |  |  | 
| 359 | 1 |  |  |  |  |  | break; | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | case rbc_not: | 
| 362 | 1 | 50 |  |  |  |  | nout = !na; | 
| 363 | 1 |  |  |  |  |  | break; | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | case rbc_abs: | 
| 366 | 3 |  |  |  |  |  | nout = fabs(na); | 
| 367 | 3 |  |  |  |  |  | break; | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | case rbc_ret: | 
| 370 | 181082 |  |  |  |  |  | return ca; | 
| 371 |  |  |  |  |  |  | break; | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | case rbc_jump: | 
| 374 |  |  |  |  |  |  | /* yes, order is important here */ | 
| 375 | 0 |  |  |  |  |  | code_count = count_base - codes->ra; | 
| 376 | 0 |  |  |  |  |  | codes = codes_base + codes->ra; | 
| 377 | 0 |  |  |  |  |  | continue; | 
| 378 |  |  |  |  |  |  |  | 
| 379 |  |  |  |  |  |  | case rbc_jumpz: | 
| 380 | 0 | 0 |  |  |  |  | if (!na) { | 
| 381 |  |  |  |  |  |  | /* yes, order is important here */ | 
| 382 | 0 |  |  |  |  |  | code_count = count_base - codes->rb; | 
| 383 | 0 |  |  |  |  |  | codes = codes_base + codes->rb; | 
| 384 | 0 |  |  |  |  |  | continue; | 
| 385 |  |  |  |  |  |  | } | 
| 386 | 0 |  |  |  |  |  | break; | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | case rbc_jumpnz: | 
| 389 | 0 | 0 |  |  |  |  | if (na) { | 
| 390 |  |  |  |  |  |  | /* yes, order is important here */ | 
| 391 | 0 |  |  |  |  |  | code_count = count_base - codes->rb; | 
| 392 | 0 |  |  |  |  |  | codes = codes_base + codes->rb; | 
| 393 | 0 |  |  |  |  |  | continue; | 
| 394 |  |  |  |  |  |  | } | 
| 395 | 0 |  |  |  |  |  | break; | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | case rbc_set: | 
| 398 | 0 |  |  |  |  |  | nout = na; | 
| 399 | 0 |  |  |  |  |  | break; | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | case rbc_setp: | 
| 402 | 0 |  |  |  |  |  | cout = ca; | 
| 403 | 0 |  |  |  |  |  | break; | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | case rbc_log: | 
| 406 | 59041 | 50 |  |  |  |  | if (na > 0) { | 
| 407 | 59041 |  |  |  |  |  | nout = log(na); | 
| 408 |  |  |  |  |  |  | } | 
| 409 |  |  |  |  |  |  | else { | 
| 410 | 0 |  |  |  |  |  | nout = DBL_MAX; | 
| 411 |  |  |  |  |  |  | } | 
| 412 | 59041 |  |  |  |  |  | break; | 
| 413 |  |  |  |  |  |  |  | 
| 414 |  |  |  |  |  |  | case rbc_exp: | 
| 415 | 2 | 100 |  |  |  |  | if (!MAX_EXP_ARG) MAX_EXP_ARG = log(DBL_MAX); | 
| 416 | 2 | 50 |  |  |  |  | if (na <= MAX_EXP_ARG) { | 
| 417 | 2 |  |  |  |  |  | nout = exp(na); | 
| 418 |  |  |  |  |  |  | } | 
| 419 |  |  |  |  |  |  | else { | 
| 420 | 0 |  |  |  |  |  | nout = DBL_MAX; | 
| 421 |  |  |  |  |  |  | } | 
| 422 | 2 |  |  |  |  |  | break; | 
| 423 |  |  |  |  |  |  |  | 
| 424 |  |  |  |  |  |  | case rbc_print: | 
| 425 | 0 |  |  |  |  |  | nout = na; | 
| 426 | 0 |  |  |  |  |  | printf("r%d is %g\n", codes->ra, na); | 
| 427 | 0 |  |  |  |  |  | break; | 
| 428 |  |  |  |  |  |  |  | 
| 429 |  |  |  |  |  |  | case rbc_det: | 
| 430 | 2 |  |  |  |  |  | nout = na*nd-nb*nc; | 
| 431 | 2 |  |  |  |  |  | break; | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | default: | 
| 434 |  |  |  |  |  |  | /*croak("bad opcode"); */ | 
| 435 | 0 |  |  |  |  |  | printf("bad op %d\n", codes->code); | 
| 436 | 0 |  |  |  |  |  | return bcol; | 
| 437 |  |  |  |  |  |  | } | 
| 438 | 1895029 |  |  |  |  |  | --code_count; | 
| 439 | 1895029 |  |  |  |  |  | ++codes; | 
| 440 |  |  |  |  |  |  | } | 
| 441 | 0 |  |  |  |  |  | return bcol; | 
| 442 |  |  |  |  |  |  | /* croak("no return opcode"); */ | 
| 443 |  |  |  |  |  |  | } |