// blit an RGBA img, blending matte colour with src alpha onto the dest void BlitMatteRGBA8( Img const& srcimg, Box const& srcbox, Img& destimg, Box& destbox, PenColour const& matte ) { assert(srcimg.Fmt()==FMT_RGBA8); Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped ); const int w = destclipped.w; int y; for( y=0; y<destclipped.h; ++y ) { RGBA8 const* src = srcimg.PtrConst_RGBA8( srcclipped.x+0, srcclipped.y+y ); switch(destimg.Fmt()) { case FMT_I8: scan_matte_RGBA8_I8(src, destimg.Ptr_I8(destclipped.x+0,destclipped.y+y), w, matte.idx()); break; case FMT_RGBX8: scan_matte_RGBA8_RGBX8(src, destimg.Ptr_RGBX8(destclipped.x+0,destclipped.y+y), w, matte.rgb()); break; case FMT_RGBA8: scan_matte_RGBA8_RGBA8(src, destimg.Ptr_RGBA8(destclipped.x+0,destclipped.y+y), w, matte.rgb()); break; default: assert(false); break; } } destbox = destclipped; }
// blit an RGBA img, blending with src alpha onto the dest (must be RGBX8 or RGBA8) void BlitRGBA8( Img const& srcimg, Box const& srcbox, Img& destimg, Box& destbox ) { assert(srcimg.Fmt()==FMT_RGBA8); assert(destimg.Fmt()!=FMT_I8); Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped ); const int w = destclipped.w; int y; for( y=0; y<destclipped.h; ++y ) { RGBA8 const* src = srcimg.PtrConst_RGBA8( srcclipped.x+0, srcclipped.y+y ); switch(destimg.Fmt()) { case FMT_I8: assert(false); // not implemented break; case FMT_RGBX8: scan_RGBA8_RGBX8(src, destimg.Ptr_RGBX8(destclipped.x+0,destclipped.y+y), w); break; case FMT_RGBA8: scan_RGBA8_RGBA8(src, destimg.Ptr_RGBA8(destclipped.x+0,destclipped.y+y), w); break; default: assert(false); break; } } destbox = destclipped; }
void BlitSwapIndexed( IndexedImg& srcimg, Box const& srcbox, IndexedImg& destimg, Box& destbox, int transparentcolour, int maskcolour ) { Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped ); int y; for( y=0; y<destclipped.h; ++y ) { uint8_t* src = srcimg.Ptr( srcclipped.x+0, srcclipped.y+y ); uint8_t* dest = destimg.Ptr( destclipped.x+0, destclipped.y+y ); // different innerloops depending on transparency/mask if( transparentcolour == -1 ) { // straight blit (maskcolour not supported) int x; for( x=0; x<destclipped.w; ++x ) { uint8_t tmp = *dest; *dest++ = *src; *src++ = tmp; } } else { int x; for( x=0; x<destclipped.w; ++x ) { uint8_t tmp = *dest; uint8_t c = *src; if( c != (uint8_t)transparentcolour ) { if( maskcolour != -1 ) c= (uint8_t)maskcolour; *dest = c; } *src++ = tmp; ++dest; } } } destbox = destclipped; }
// TODO: src,dest names meaningless. Should be a,b or something neutral void BlitSwap( Img& srcimg, Box const& srcbox, Img& destimg, Box& destbox) { assert( srcimg.Fmt() == destimg.Fmt()); Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped ); int y; for( y=0; y<destclipped.h; ++y ) { switch(srcimg.Fmt()) { case FMT_I8: { I8* src = srcimg.Ptr_I8( srcclipped.x+0, srcclipped.y+y ); I8* dest = destimg.Ptr_I8( destclipped.x+0, destclipped.y+y ); std::swap_ranges( src,src+destclipped.w, dest); } break; case FMT_RGBX8: { RGBX8* src = srcimg.Ptr_RGBX8( srcclipped.x+0, srcclipped.y+y ); RGBX8* dest = destimg.Ptr_RGBX8( destclipped.x+0, destclipped.y+y ); std::swap_ranges( src,src+destclipped.w, dest); } break; case FMT_RGBA8: { RGBA8* src = srcimg.Ptr_RGBA8( srcclipped.x+0, srcclipped.y+y ); RGBA8* dest = destimg.Ptr_RGBA8( destclipped.x+0, destclipped.y+y ); std::swap_ranges( src,src+destclipped.w, dest); } break; default: assert(false); break; } } destbox = destclipped; }
void BlitZoomIndexedToRGBx( IndexedImg const& srcimg, Box const& srcbox, RGBImg& destimg, Box& destbox, Palette const& palette, int zoom, int transparentcolour, int maskcolour ) { assert( srcimg.Bounds().Contains( srcbox ) ); assert( zoom >= 1 ); Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped, zoom ); int y; for( y=0; y<destclipped.H(); ++y ) { int x; RGBx* dest = destimg.Ptr( destclipped.XMin() + 0, destclipped.YMin() + y ); uint8_t const* src = srcimg.PtrConst( srcclipped.XMin()+0, srcclipped.YMin()+y/zoom ); int n=0; for( x=0; x<destclipped.W(); ++x ) { RGBx c;// = *dest; if( maskcolour != -1 ) c = palette.GetColour(maskcolour); else c = palette.GetColour(*src); if( *src != transparentcolour ) *dest = c; ++dest; if( ++n >= zoom ) { ++src; n=0; } } } }
// blit from an I8 source to any target, with colourkey transparency void BlitI8Keyed( Img const& srcimg, Box const& srcbox, Palette const& srcpalette, Img& destimg, Box& destbox, int transparentIdx ) { assert(srcimg.Fmt()==FMT_I8); Box destclipped( destbox ); Box srcclipped( srcbox ); clip_blit( srcimg.Bounds(), srcclipped, destimg.Bounds(), destclipped ); const int w = destclipped.w; int y; for( y=0; y<destclipped.h; ++y ) { I8 const* src = srcimg.PtrConst_I8( srcclipped.x+0, srcclipped.y+y ); switch(destimg.Fmt()) { case FMT_I8: scan_I8_I8_keyed(src, destimg.Ptr_I8(destclipped.x+0,destclipped.y+y), w, transparentIdx); break; case FMT_RGBX8: scan_I8_RGBX8_keyed(src, srcpalette, destimg.Ptr_RGBX8(destclipped.x+0,destclipped.y+y), w, transparentIdx); break; case FMT_RGBA8: scan_I8_RGBA8_keyed(src, srcpalette, destimg.Ptr_RGBA8(destclipped.x+0,destclipped.y+y), w, transparentIdx); break; default: assert(false); break; } } destbox = destclipped; }