| 377 | |
| 378 | template<bool processR, bool processG, bool processB, bool processA> |
| 379 | void process(const OfxRectI& procWindow, const OfxPointD& rs) |
| 380 | { |
| 381 | unused(rs); |
| 382 | assert( (!processR && !processG && !processB) || (nComponents == 3 || nComponents == 4) ); |
| 383 | assert( !processA || (nComponents == 1 || nComponents == 4) ); |
| 384 | assert(nComponents == 3 || nComponents == 4); |
| 385 | float unpPix[4] = {0.f, 0.f, 0.f, 0.f}; |
| 386 | float tmpPix[4] = {0.f, 0.f, 0.f, 0.f}; |
| 387 | // set up a random number generator and set the seed |
| 388 | #ifdef USE_RANDOMGENERATOR |
| 389 | RandomGenerator randy; |
| 390 | #endif |
| 391 | double randValue; |
| 392 | for (int y = procWindow.y1; y < procWindow.y2; y++) { |
| 393 | if ( _effect.abort() ) { |
| 394 | break; |
| 395 | } |
| 396 | |
| 397 | PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y); |
| 398 | for (int x = procWindow.x1; x < procWindow.x2; x++) { |
| 399 | // for a given x,y position, the output should always be the same. |
| 400 | if (_dither == eDitherRandom) { |
| 401 | # ifdef USE_RANDOMGENERATOR |
| 402 | randy.reseed(hash(x + 0x10000 * _seed) + y); |
| 403 | randValue = randy.random(); |
| 404 | # else |
| 405 | randValue = hash(hash(hash(_seed ^ x) ^ y) ^ nComponents) / ( (double)0x100000000ULL ); |
| 406 | # endif |
| 407 | } |
| 408 | |
| 409 | const PIX *srcPix = (const PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0); |
| 410 | ofxsUnPremult<PIX, nComponents, maxValue>(srcPix, unpPix, _premult, _premultChannel); |
| 411 | |
| 412 | // process the pixel (the actual computation goes here) |
| 413 | switch (_dither) { |
| 414 | case eDitherNone: { |
| 415 | // no dithering (identical tu Nuke's Posterize) |
| 416 | for (int c = 0; c < 4; ++c) { |
| 417 | float rounded = (unpPix[c] <= 0) ? std::floor(unpPix[c] * _colors) : std::ceil(unpPix[c] * _colors - 1.); |
| 418 | //tmpPix[c] = std::floor(unpPix[c] * _colors) / (_colors - 1.); // ok except when unpPix[c] * _colors is a positive integer |
| 419 | tmpPix[c] = rounded / (_colors - 1.); |
| 420 | } |
| 421 | break; |
| 422 | } |
| 423 | case eDitherOrderedBayer2: { |
| 424 | // 2x2 Bayer |
| 425 | #undef MSIZE |
| 426 | #define MSIZE 2 |
| 427 | int subx = x % MSIZE; |
| 428 | if (subx < 0) { |
| 429 | subx += MSIZE; |
| 430 | } |
| 431 | int suby = y % MSIZE; |
| 432 | if (suby < 0) { |
| 433 | suby += MSIZE; |
| 434 | } |
| 435 | int dith = bayer2[subx][suby]; |
| 436 | for (int c = 0; c < 4; ++c) { |
no test coverage detected