/* This code is shared by six methods. Write value of pixel w|h in data to pixel nw|nh in pResBits. Antialias if requested. */ void DistortionFXFilter::setPixelFromOther(int Width, int Height, bool sixteenBit, int bytesDepth, uchar* data, uchar* pResBits, int w, int h, double nw, double nh, bool AntiAlias) { DColor color; int offset = getOffset(Width, w, h, bytesDepth); if (AntiAlias) { uchar* const ptr = pResBits + offset; if (sixteenBit) { unsigned short* ptr16 = reinterpret_cast<unsigned short*>(ptr); PixelsAliasFilter().pixelAntiAliasing16(reinterpret_cast<unsigned short*>(data), Width, Height, nw, nh, ptr16 + 3, ptr16 + 2, ptr16 + 1, ptr16); } else { PixelsAliasFilter().pixelAntiAliasing(data, Width, Height, nw, nh, ptr + 3, ptr + 2, ptr + 1, ptr); } } else { // we get the position adjusted int offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth); // read color color.setColor(data + offsetOther, sixteenBit); // write color to destination color.setPixel(pResBits + offset); } }
void DistortionFXFilter::blockWavesMultithreaded(const Args& prm) { int Width = prm.orgImage->width(); int Height = prm.orgImage->height(); uchar* data = prm.orgImage->bits(); bool sixteenBit = prm.orgImage->sixteenBit(); int bytesDepth = prm.orgImage->bytesDepth(); uchar* pResBits = prm.destImage->bits(); int nw, nh; DColor color; int offset, offsetOther; int nHalfW = Width / 2; int nHalfH = Height / 2; for (int h = prm.start; runningFlag() && (h < prm.stop); ++h) { nw = nHalfW - prm.w; nh = nHalfH - h; if (prm.Mode) { nw = (int)(prm.w + prm.Amplitude * qSin(prm.Frequency * nw * (M_PI / 180))); nh = (int)(h + prm.Amplitude * qCos(prm.Frequency * nh * (M_PI / 180))); } else { nw = (int)(prm.w + prm.Amplitude * qSin(prm.Frequency * prm.w * (M_PI / 180))); nh = (int)(h + prm.Amplitude * qCos(prm.Frequency * h * (M_PI / 180))); } offset = getOffset(Width, prm.w, h, bytesDepth); offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth); // read color color.setColor(data + offsetOther, sixteenBit); // write color to destination color.setPixel(pResBits + offset); } }
void DistortionFXFilter::twirlMultithreaded(const Args& prm) { int Width = prm.orgImage->width(); int Height = prm.orgImage->height(); uchar* data = prm.orgImage->bits(); bool sixteenBit = prm.orgImage->sixteenBit(); int bytesDepth = prm.orgImage->bytesDepth(); uchar* pResBits = prm.destImage->bits(); DColor color; int offset; int nHalfW = Width / 2; int nHalfH = Height / 2; double lfXScale = 1.0; double lfYScale = 1.0; double lfAngle, lfNewAngle, lfAngleSum, lfCurrentRadius; double tw, nh, nw; if (Width > Height) { lfYScale = (double)Width / (double)Height; } else if (Height > Width) { lfXScale = (double)Height / (double)Width; } // the angle step is dist divided by 10000 double lfAngleStep = prm.dist / 10000.0; // now, we get the minimum radius double lfRadMax = (double)qMax(Width, Height) / 2.0; double th = lfYScale * (double)(prm.h - nHalfH); for (int w = prm.start; runningFlag() && (w < prm.stop); ++w) { tw = lfXScale * (double)(w - nHalfW); // now, we get the distance lfCurrentRadius = qSqrt(th * th + tw * tw); // if distance is less than maximum radius... if (lfCurrentRadius < lfRadMax) { // we find the angle from the center lfAngle = qAtan2(th, tw); // we get the accumuled angle lfAngleSum = lfAngleStep * (-1.0 * (lfCurrentRadius - lfRadMax)); // ok, we sum angle with accumuled to find a new angle lfNewAngle = lfAngle + lfAngleSum; // now we find the exact position's x and y nw = (double)nHalfW + qCos(lfNewAngle) * (lfCurrentRadius / lfXScale); nh = (double)nHalfH + qSin(lfNewAngle) * (lfCurrentRadius / lfYScale); setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, prm.h, nw, nh, prm.AntiAlias); } else { // copy pixel offset = getOffset(Width, w, prm.h, bytesDepth); color.setColor(data + offset, sixteenBit); color.setPixel(pResBits + offset); } } }
void DistortionFXFilter::fisheyeMultithreaded(const Args& prm) { int Width = prm.orgImage->width(); int Height = prm.orgImage->height(); uchar* data = prm.orgImage->bits(); bool sixteenBit = prm.orgImage->sixteenBit(); int bytesDepth = prm.orgImage->bytesDepth(); uchar* pResBits = prm.destImage->bits(); double nh, nw, tw; DColor color; int offset; int nHalfW = Width / 2; int nHalfH = Height / 2; double lfXScale = 1.0; double lfYScale = 1.0; double lfCoeffStep = prm.Coeff / 1000.0; double lfRadius, lfAngle; if (Width > Height) { lfYScale = (double)Width / (double)Height; } else if (Height > Width) { lfXScale = (double)Height / (double)Width; } double lfRadMax = (double)qMax(Height, Width) / 2.0; double lfCoeff = lfRadMax / qLn(qFabs(lfCoeffStep) * lfRadMax + 1.0); double th = lfYScale * (double)(prm.h - nHalfH); for (int w = prm.start; runningFlag() && (w < prm.stop); ++w) { tw = lfXScale * (double)(w - nHalfW); // we find the distance from the center lfRadius = qSqrt(th * th + tw * tw); if (lfRadius < lfRadMax) { lfAngle = qAtan2(th, tw); if (prm.Coeff > 0.0) { lfRadius = (qExp(lfRadius / lfCoeff) - 1.0) / lfCoeffStep; } else { lfRadius = lfCoeff * qLn(1.0 + (-1.0 * lfCoeffStep) * lfRadius); } nw = (double)nHalfW + (lfRadius / lfXScale) * qCos(lfAngle); nh = (double)nHalfH + (lfRadius / lfYScale) * qSin(lfAngle); setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, prm.h, nw, nh, prm.AntiAlias); } else { // copy pixel offset = getOffset(Width, w, prm.h, bytesDepth); color.setColor(data + offset, sixteenBit); color.setPixel(pResBits + offset); } } }