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 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 ); }
Area findNonTransparentArea( const SurfaceT<T> &surface, const Area &unclippedBounds ) { const Area bounds = unclippedBounds.getClipBy( surface.getBounds() ); // if no alpha we'll fail over the to alpha-less fill if( ! surface.hasAlpha() ) { return surface.getBounds(); } int32_t topLine, bottomLine; int32_t leftColumn, rightColumn; // find the top and bottom lines for( topLine = bounds.getY1(); topLine < bounds.getY2(); ++topLine ) { if( ! transparentHorizontalScanline( surface, topLine, bounds.getX1(), bounds.getX2() ) ) { break; } } for( bottomLine = bounds.getY2() - 1; bottomLine > topLine; --bottomLine ) { if( ! transparentHorizontalScanline( surface, bottomLine, bounds.getX1(), bounds.getX2() ) ) { break; } } // find the left and right columns for( leftColumn = bounds.getX1(); leftColumn < bounds.getX2(); ++leftColumn ) { if( ! transparentVerticalScanline( surface, leftColumn, topLine, bottomLine ) ) { break; } } for( rightColumn = bounds.getX2(); rightColumn > leftColumn; --rightColumn ) { if( ! transparentVerticalScanline( surface, rightColumn, topLine, bottomLine ) ) { break; } } // we add one to right and bottom because Area represents an inclusive range on top/left and exclusive range on bottom/right rightColumn = std::min( bounds.getX2(), rightColumn + 1 ); bottomLine = std::min( bounds.getY2(), bottomLine + 1 ); return Area( leftColumn, topLine, rightColumn, bottomLine ); }
void flipVertical( const SurfaceT<T> &srcSurface, SurfaceT<T> *destSurface ) { std::pair<Area,ivec2> srcDst = clippedSrcDst( srcSurface.getBounds(), destSurface->getBounds(), destSurface->getBounds(), ivec2(0,0) ); if( destSurface->getChannelOrder() == srcSurface.getChannelOrder() ) flipVerticalRawSameChannelOrder( srcSurface, destSurface, srcDst.first.getSize() ); else if( destSurface->hasAlpha() && srcSurface.hasAlpha() ) flipVerticalRawRgba( srcSurface, destSurface, srcDst.first.getSize() ); else if( destSurface->hasAlpha() && ( ! srcSurface.hasAlpha() ) ) flipVerticalRawRgbFullAlpha( srcSurface, destSurface, srcDst.first.getSize() ); else flipVerticalRawRgb( srcSurface, destSurface, srcDst.first.getSize() ); }
void threshold( const SurfaceT<T> &surface, T value, SurfaceT<T> *dstSurface ) { thresholdImpl( surface, value, surface.getBounds(), ivec2(), dstSurface ); }
void edgeDetectSobel( const SurfaceT<T> &srcSurface, SurfaceT<T> *dstSuface ) { edgeDetectSobel( srcSurface, srcSurface.getBounds(), Vec2i::zero(), dstSuface ); }