the following only works for increasing LUTs
| 264 | |
| 265 | // the following only works for increasing LUTs |
| 266 | unsigned short |
| 267 | Lut::toColorSpaceUint16FromLinearFloatFast(float v) const |
| 268 | { |
| 269 | assert(init_); |
| 270 | // algorithm: |
| 271 | // - convert to 8 bits -> val8u |
| 272 | // - convert val8u-1, val8u and val8u+1 to float |
| 273 | // - interpolate linearly in the right interval |
| 274 | unsigned char v8u = toColorSpaceUint8FromLinearFloatFast(v); |
| 275 | unsigned char v8u_next, v8u_prev; |
| 276 | float v32f_next, v32f_prev; |
| 277 | if (v8u == 0) { |
| 278 | v8u_prev = 0; |
| 279 | v8u_next = 1; |
| 280 | v32f_prev = fromColorSpaceUint8ToLinearFloatFast(0); |
| 281 | v32f_next = fromColorSpaceUint8ToLinearFloatFast(1); |
| 282 | } else if (v8u == 255) { |
| 283 | v8u_prev = 254; |
| 284 | v8u_next = 255; |
| 285 | v32f_prev = fromColorSpaceUint8ToLinearFloatFast(254); |
| 286 | v32f_next = fromColorSpaceUint8ToLinearFloatFast(255); |
| 287 | } else { |
| 288 | float v32f = fromColorSpaceUint8ToLinearFloatFast(v8u); |
| 289 | // we suppose the LUT is an increasing func |
| 290 | if (v < v32f) { |
| 291 | v8u_prev = v8u - 1; |
| 292 | v32f_prev = fromColorSpaceUint8ToLinearFloatFast(v8u_prev); |
| 293 | v8u_next = v8u; |
| 294 | v32f_next = v32f; |
| 295 | } else { |
| 296 | v8u_prev = v8u; |
| 297 | v32f_prev = v32f; |
| 298 | v8u_next = v8u + 1; |
| 299 | v32f_next = fromColorSpaceUint8ToLinearFloatFast(v8u_next); |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | // interpolate linearly |
| 304 | return (v8u_prev << 8) + v8u_prev + (v - v32f_prev) * ( ( (v8u_next - v8u_prev) << 8 ) + (v8u_next + v8u_prev) ) / (v32f_next - v32f_prev) + 0.5; |
| 305 | } |
| 306 | |
| 307 | float |
| 308 | Lut::fromColorSpaceUint16ToLinearFloatFast(unsigned short v) const |
no outgoing calls
no test coverage detected