' imgput() ... draw flip, transpose, 90/180 degree rotation. ' by counting_pine ' https://www.freebasic.net/forum/viewtopic.php?t=12074 #ifndef __IMGPUT__ #define __IMGPUT__ #include "crt.bi" enum IMGPUT_TRANSFORM TRANSFORM_HFLIP = 1 TRANSFORM_VFLIP = 2 TRANSFORM_D1FLIP = 4 TRANSFORM_R90 = TRANSFORM_HFLIP or TRANSFORM_D1FLIP TRANSFORM_R180 = TRANSFORM_HFLIP or TRANSFORM_VFLIP TRANSFORM_R270 = TRANSFORM_VFLIP or TRANSFORM_D1FLIP TRANSFORM_D2FLIP = TRANSFORM_R180 or TRANSFORM_D1FLIP TRANSFORM_NONE = 0 end enum sub imgput overload( _ byval srcImg as any ptr, _ byval dstImg as any ptr = 0, _ byval x as integer = 0, byval y as integer = 0 ) dim as integer srcWidth, srcHeight, srcBypp, srcPitch dim as integer dstWidth, dstHeight, dstBypp, dstPitch dim as integer srcXLow, srcXUpp, srcYLow, srcYUpp dim as integer dstXLow, dstXUpp, dstYLow, dstYUpp dim as any ptr srcPData, spr dim as any ptr dstPData, dpr dim as integer screenDest = 0 dim as integer rowBytes if imageinfo( srcImg, srcWidth, srcHeight, srcBypp, srcPitch, srcPData ) then exit sub if dstImg <> 0 then if imageinfo( dstImg, dstWidth, dstHeight, dstBypp, dstPitch, dstPData ) then exit sub else dstPData = screenptr: if dstPData = 0 then exit sub screeninfo( dstWidth, dstHeight, , dstBypp, dstPitch ) screenDest = 1 end if if srcBypp <> dstBypp then exit sub srcXLow = 0: srcXUpp = srcWidth - 1 srcYLow = 0: srcYUpp = srcHeight - 1 '' clipping dstXLow = x: dstXUpp = x + srcXUpp - srcXLow dstYLow = y: dstYUpp = y + srcYUpp - srcYLow if dstXLow < 0 then srcXLow -= dstXLow: dstXLow = 0 if dstYLow < 0 then srcYLow -= dstYLow: dstYLow = 0 if dstXUpp >= dstWidth then srcXUpp += dstWidth-1 - dstXUpp: dstXUpp = dstWidth-1 if dstYUpp >= dstHeight then srcYUpp += dstHeight-1 - dstYUpp: dstYUpp = dstHeight-1 '' find starting corner addresses spr = srcPData + srcYLow * srcPitch + srcXLow * srcBypp dpr = dstPData + dstYLow * dstPitch + dstXLow * dstBypp '' put image #macro PUT_ROWS() rowBytes = srcBypp * (srcXUpp - srcXLow + 1) for y = srcYLow to srcYUpp memcpy( dpr, spr, rowBytes ) spr += srcPitch dpr += dstPitch next y #endmacro if screenDest then screenlock PUT_ROWS() if screenDest then screenunlock end sub sub imgput overload( _ byval srcImg as any ptr, _ byval dstImg as any ptr = 0, _ byval x as integer = 0, byval y as integer = 0, _ byval transform as IMGPUT_TRANSFORM ) dim as integer srcWidth, srcHeight, srcBypp, srcPitch dim as integer dstWidth, dstHeight, dstBypp, dstPitch dim as integer srcXLow, srcXUpp, srcYLow, srcYUpp, srcDx, srcDy dim as integer dstXLow, dstXUpp, dstYLow, dstYUpp, dstDx, dstDy dim as const integer ptr srcPX1 = @srcXLow, srcPX2 = @srcXUpp dim as const integer ptr srcPY1 = @srcYLow, srcPY2 = @srcYUpp dim as any ptr srcPData, spr, sp dim as any ptr dstPData, dpr, dp dim as integer screenDest = 0 dim as integer rowBytes if imageinfo( srcImg, srcWidth, srcHeight, srcBypp, srcPitch, srcPData ) then exit sub if dstImg <> 0 then if imageinfo( dstImg, dstWidth, dstHeight, dstBypp, dstPitch, dstPData ) then exit sub else dstPData = screenptr: if dstPData = 0 then exit sub screeninfo( dstWidth, dstHeight, , dstBypp, dstPitch ) screenDest = 1 end if if srcBypp <> dstBypp then exit sub srcDx = srcBypp: srcDy = srcPitch srcXLow = 0: srcXUpp = srcWidth - 1 srcYLow = 0: srcYUpp = srcHeight - 1 dstDx = dstBypp: dstDy = dstPitch '' set up transform if (transform and TRANSFORM_D1FLIP) then swap srcDx, srcDy swap srcXLow, srcYLow swap srcXUpp, srcYUpp end if if (transform and TRANSFORM_HFLIP) then srcDx = -srcDx: swap srcPX1, srcPX2 if (transform and TRANSFORM_VFLIP) then srcDy = -srcDy: swap srcPY1, srcPY2 '' clipping dstXLow = x: dstXUpp = x + srcXUpp - srcXLow dstYLow = y: dstYUpp = y + srcYUpp - srcYLow if dstXLow < 0 then srcXLow -= dstXLow: dstXLow = 0 if dstYLow < 0 then srcYLow -= dstYLow: dstYLow = 0 if dstXUpp >= dstWidth then srcXUpp += dstWidth-1 - dstXUpp: dstXUpp = dstWidth-1 if dstYUpp >= dstHeight then srcYUpp += dstHeight-1 - dstYUpp: dstYUpp = dstHeight-1 '' find starting corner addresses spr = srcPData + *srcPY1 * abs(srcDy) + *srcPX1 * abs(srcDx) dpr = dstPData + dstYLow * abs(dstDy) + dstXLow * abs(dstDx) '' put image #macro PUT_TYPE( t ) for y = srcYLow to srcYUpp sp = spr dp = dpr for x = srcXLow to srcXUpp *cast( t ptr, dp ) = *cast(t ptr, sp ) sp += srcDx dp += dstDx next x spr += srcDy dpr += dstDy next y #endmacro #macro PUT_ROWS() rowBytes = srcBypp * (srcXUpp - srcXLow + 1) for y = srcYLow to srcYUpp memcpy( dpr, spr, rowBytes ) spr += srcDy dpr += dstDy next y #endmacro if screenDest then screenlock if srcDx = srcBypp then PUT_ROWS() else select case SrcBypp case 1: PUT_TYPE( ubyte ) case 2: PUT_TYPE( ushort ) case 4: PUT_TYPE( uinteger ) end select end if if screenDest then screenunlock end sub sub imgput overload( _ byval srcImg as any ptr, _ byval dstImg as any ptr = 0, _ byval x as integer = 0, byval y as integer = 0, _ byval transform as integer ) if transform and -8 then select case transform mod 360 case 0: transform = TRANSFORM_NONE case 90, -270: transform = TRANSFORM_R90 case 180, -180: transform = TRANSFORM_R180 case 270, -90: transform = TRANSFORM_R270 end select end if imgput( srcImg, dstImg, x, y, cast(IMGPUT_TRANSFORM, transform) ) end sub #endif