void thresholdImpl( const SurfaceT<T> &srcSurface, T value, const Area &srcArea, const ivec2 &dstLT, SurfaceT<T> *dstSurface ) { std::pair<Area,ivec2> srcDst = clippedSrcDst( srcSurface.getBounds(), srcArea, dstSurface->getBounds(), dstLT ); const Area &area( srcDst.first ); const ivec2 &dstOffset( srcDst.second ); ptrdiff_t srcRowBytes = srcSurface.getRowBytes(); uint8_t srcPixelInc = srcSurface.getPixelInc(); uint8_t srcRedOffset = srcSurface.getRedOffset(), srcGreenOffset = srcSurface.getGreenOffset(), srcBlueOffset = srcSurface.getBlueOffset(); ptrdiff_t dstRowBytes = dstSurface->getRowBytes(); uint8_t dstPixelInc = dstSurface->getPixelInc(); uint8_t dstRedOffset = dstSurface->getRedOffset(), dstGreenOffset = dstSurface->getGreenOffset(), dstBlueOffset = dstSurface->getBlueOffset(); const T maxValue = CHANTRAIT<T>::max(); for( int32_t y = 0; y < area.getHeight(); ++y ) { T *dstPtr = reinterpret_cast<T*>( reinterpret_cast<uint8_t*>( dstSurface->getData() + ( dstOffset.x + area.getX1() ) * dstPixelInc ) + ( y + dstOffset.y ) * dstRowBytes ); const T *srcPtr = reinterpret_cast<const T*>( reinterpret_cast<const uint8_t*>( srcSurface.getData() + area.getX1() * srcPixelInc ) + ( y + area.getY1() ) * srcRowBytes ); for( int32_t x = area.getX1(); x < area.getX2(); ++x ) { dstPtr[dstRedOffset] = ( srcPtr[srcRedOffset] > value ) ? maxValue : 0; dstPtr[dstGreenOffset] = ( srcPtr[srcGreenOffset] > value ) ? maxValue : 0; dstPtr[dstBlueOffset] = ( srcPtr[srcBlueOffset] > value ) ? maxValue : 0;; dstPtr += dstPixelInc; srcPtr += srcPixelInc; } } }
void edgeDetectSobel( const ChannelT<T> &srcChannel, const Area &srcArea, const Vec2i &dstLT, ChannelT<T> *dstChannel ) { std::pair<Area,Vec2i> srcDst = clippedSrcDst( srcChannel.getBounds(), srcArea, dstChannel->getBounds(), dstLT ); const Area &area( srcDst.first ); const Vec2i &dstOffset( srcDst.second ); typename CHANTRAIT<T>::Sum sumX, sumY; int32_t srcRowBytes = srcChannel.getRowBytes(); int8_t srcPixelBytes = srcChannel.getIncrement() * sizeof(T); int8_t dstPixelBytes = dstChannel->getIncrement() * sizeof(T); const T maxValue = CHANTRAIT<T>::max(); for( int32_t y = 1; y < area.getHeight() - 1; ++y ) { const uint8_t *srcLine = reinterpret_cast<const uint8_t*>( srcChannel.getData( area.getX1() + 1, area.getY1() + y ) ); uint8_t *dstLine = reinterpret_cast<uint8_t*>( dstChannel->getData( dstOffset.x + area.getX1() + 1, dstOffset.y + y ) ); for( int32_t x = area.getX1() + 1; x < area.getX2() - 1; ++x ) { // sumX = -srcLine[-srcRowPixels-srcPixelStride] + srcLine[-srcRowPixels+srcPixelStride] - 2 * srcLine[-srcPixelStride] + 2 * srcLine[srcPixelStride] - srcLine[srcRowPixels-srcPixelStride] + srcLine[srcRowPixels+srcPixelStride]; sumX = -*(T*)(srcLine-srcRowBytes-srcPixelBytes) + *(T*)(srcLine-srcRowBytes+srcPixelBytes) - 2 * *(T*)(srcLine-srcPixelBytes) + 2 * *(T*)(srcLine+srcPixelBytes) - *(T*)(srcLine+srcRowBytes-srcPixelBytes) + *(T*)(srcLine+srcRowBytes+srcPixelBytes); // sumY = srcLine[-srcRowPixels-srcPixelStride] + 2 * srcLine[-srcRowPixels] + srcLine[-srcRowPixels + srcPixelStride] - srcLine[srcRowPixels-srcPixelStride] - 2 * srcLine[srcRowPixels] - srcLine[srcRowPixels+srcPixelStride]; sumY = *(T*)(srcLine-srcRowBytes-srcPixelBytes) + 2 * *(T*)(srcLine-srcRowBytes) + *(T*)(srcLine-srcRowBytes+srcPixelBytes) - *(T*)(srcLine+srcRowBytes-srcPixelBytes) - 2 * *(T*)(srcLine+srcPixelBytes) - *(T*)(srcLine+srcRowBytes+srcPixelBytes); sumX = static_cast<typename CHANTRAIT<T>::Sum>( math<float>::sqrt( float( sumX * sumX + sumY * sumY ) ) ); if( sumX > maxValue ) sumX = maxValue; *dstLine = static_cast<uint8_t>( sumX ); dstLine += dstPixelBytes; srcLine += srcPixelBytes; } } }
void SurfaceT<T>::copyFrom( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &relativeOffset ) { std::pair<Area,Vec2i> srcDst = clippedSrcDst( srcSurface.getBounds(), srcArea, getBounds(), srcArea.getUL() + relativeOffset ); if( getChannelOrder() == srcSurface.getChannelOrder() ) copyRawSameChannelOrder( srcSurface, srcDst.first, srcDst.second ); else if( hasAlpha() && srcSurface.hasAlpha() ) copyRawRgba( srcSurface, srcDst.first, srcDst.second ); else copyRawRgb( srcSurface, srcDst.first, srcDst.second ); }
void thresholdImpl( const ChannelT<T> &srcChannel, T value, const Area &srcArea, const ivec2 &dstLT, ChannelT<T> *dstChannel ) { std::pair<Area,ivec2> srcDst = clippedSrcDst( srcChannel.getBounds(), srcArea, dstChannel->getBounds(), dstLT ); const Area &area( srcDst.first ); const ivec2 &dstOffset( srcDst.second ); uint8_t srcInc = srcChannel.getIncrement(); uint8_t dstInc = dstChannel->getIncrement(); const T maxValue = CHANTRAIT<T>::max(); for( int32_t y = 0; y < area.getHeight(); ++y ) { T *dstPtr = dstChannel->getData( ivec2( area.getX1(), y ) + dstOffset ); const T *srcPtr = srcChannel.getData( ivec2( area.getX1(), y ) ); for( int32_t x = area.getX1(); x < area.getX2(); ++x ) { *dstPtr = ( *srcPtr > value ) ? maxValue : 0; dstPtr += dstInc; srcPtr += srcInc; } } }
void ChannelT<T>::copyFrom( const ChannelT<T> &srcChannel, const Area &srcArea, const ivec2 &relativeOffset ) { std::pair<Area,ivec2> srcDst = clippedSrcDst( srcChannel.getBounds(), srcArea, getBounds(), srcArea.getUL() + relativeOffset ); int32_t srcRowBytes = srcChannel.getRowBytes(); uint8_t srcIncrement = srcChannel.getIncrement(); uint8_t increment = mIncrement; int32_t width = srcDst.first.getWidth(); for( int32_t y = 0; y < srcArea.getHeight(); ++y ) { const T *src = reinterpret_cast<const T*>( reinterpret_cast<const uint8_t*>( srcChannel.mData + srcArea.x1 * srcIncrement ) + ( srcArea.y1 + y ) * srcRowBytes ); T *dst = reinterpret_cast<T*>( reinterpret_cast<uint8_t*>( mData + srcDst.second.x * mIncrement ) + ( y + srcDst.second.y ) * mRowBytes ); for( int32_t x = 0; x < width; ++x ) { *dst = *src; src += srcIncrement; dst += increment; } } }