/* * Copyright (C) 2010-2022 Arm Limited or its affiliates. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* ---------------------------------------------------------------------- * Project: Arm-2D Library * Title: arm-2d_transform.c * Description: APIs for tile transform * * $Date: 20 May 2022 * $Revision: V.1.0.3 * * Target Processor: Cortex-M cores * * -------------------------------------------------------------------- */ /*============================ INCLUDES ======================================*/ #define __ARM_2D_IMPL__ #include "arm_2d.h" #include "__arm_2d_impl.h" #include "math.h" #ifdef __cplusplus extern "C" { #endif #if defined(__clang__) # pragma clang diagnostic ignored "-Wunknown-warning-option" # pragma clang diagnostic ignored "-Wreserved-identifier" # pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers" # pragma clang diagnostic ignored "-Wmissing-variable-declarations" # pragma clang diagnostic ignored "-Wcast-qual" # pragma clang diagnostic ignored "-Wcast-align" # pragma clang diagnostic ignored "-Wextra-semi-stmt" # pragma clang diagnostic ignored "-Wsign-conversion" # pragma clang diagnostic ignored "-Wunused-function" # pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" # pragma clang diagnostic ignored "-Wdouble-promotion" # pragma clang diagnostic ignored "-Wunused-parameter" # pragma clang diagnostic ignored "-Wimplicit-float-conversion" # pragma clang diagnostic ignored "-Wimplicit-int-conversion" # pragma clang diagnostic ignored "-Wtautological-pointer-compare" # pragma clang diagnostic ignored "-Wsign-compare" # pragma clang diagnostic ignored "-Wfloat-conversion" # pragma clang diagnostic ignored "-Wmissing-prototypes" # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wundef" # pragma clang diagnostic ignored "-Wdeclaration-after-statement" #elif defined(__IS_COMPILER_ARM_COMPILER_5__) # pragma diag_suppress 174,177,188,68,513,144,1296 #elif defined(__IS_COMPILER_IAR__) # pragma diag_suppress=Pa093 #elif defined(__IS_COMPILER_GCC__) # pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" #endif #include /*============================ MACROS ========================================*/ #undef __PI #define __PI 3.1415926f #define __CALIB 0.009f /* faster ATAN */ #define FAST_ATAN_F32_1(x, xabs) \ (x * (PI / 4.0f) + 0.273f * x * (1.0f - xabs)) #define EPS_ATAN2 1e-5f #define TO_Q16(x) ((int32_t)(x) << 16) /*----------------------------------------------------------------------------* * Code Template * *----------------------------------------------------------------------------*/ #define __API_PIXEL_AVERAGE_RESULT_GRAY8() \ ( tPixel >> 8) #define __API_PIXEL_AVERAGE_RESULT_RGB565() \ ( tPixel.R >>= 8, \ tPixel.G >>= 8, \ tPixel.B >>= 8, \ __arm_2d_rgb565_pack(&tPixel)) #define __API_PIXEL_AVERAGE_RESULT_CCCN888() \ ( tPixel.R >>= 8, \ tPixel.G >>= 8, \ tPixel.B >>= 8, \ tPixel.A = *((uint8_t *)pTarget + 3), \ __arm_2d_cccn888_pack(&tPixel)) #define __API_COLOUR gray8 #define __API_INT_TYPE uint8_t #define __API_INT_TYPE_BIT_NUM 16 #define __API_PIXEL_AVERAGE_INIT() uint16_t tPixel = 0; #define __API_PIXEL_BLENDING __ARM_2D_PIXEL_BLENDING_OPA_GRAY8 #define __API_PIXEL_AVERAGE __ARM_2D_PIXEL_AVERAGE_GRAY8 #define __API_PIXEL_AVERAGE_RESULT __API_PIXEL_AVERAGE_RESULT_GRAY8 #include "__arm_2d_transform.inc" #define __API_COLOUR rgb565 #define __API_INT_TYPE uint16_t #define __API_INT_TYPE_BIT_NUM 16 #define __API_PIXEL_BLENDING __ARM_2D_PIXEL_BLENDING_OPA_RGB565 #define __API_PIXEL_AVERAGE __ARM_2D_PIXEL_AVERAGE_RGB565 #define __API_PIXEL_AVERAGE_RESULT __API_PIXEL_AVERAGE_RESULT_RGB565 #include "__arm_2d_transform.inc" #define __API_COLOUR cccn888 #define __API_INT_TYPE uint32_t #define __API_INT_TYPE_BIT_NUM 32 #define __API_PIXEL_BLENDING __ARM_2D_PIXEL_BLENDING_OPA_CCCN888 #define __API_PIXEL_AVERAGE __ARM_2D_PIXEL_AVERAGE_CCCN888 #define __API_PIXEL_AVERAGE_RESULT __API_PIXEL_AVERAGE_RESULT_CCCN888 #include "__arm_2d_transform.inc" /*============================ MACROFIED FUNCTIONS ===========================*/ /*============================ TYPES =========================================*/ /*============================ GLOBAL VARIABLES ==============================*/ /*============================ PROTOTYPES ====================================*/ /*============================ LOCAL VARIABLES ===============================*/ /*============================ IMPLEMENTATION ================================*/ /*----------------------------------------------------------------------------* * Utilities * *----------------------------------------------------------------------------*/ __arm_2d_point_adj_alpha_t __arm_2d_point_get_adjacent_alpha_fp(arm_2d_point_float_t *ptPoint) { assert(NULL != ptPoint); float x = ptPoint->fX - (int32_t)ptPoint->fX; float y = ptPoint->fY - (int32_t)ptPoint->fY; int16_t iXSign = x < 0 ; int16_t iYSign = y < 0 ; __arm_2d_point_adj_alpha_t tResult = { .tMatrix = { [0] = { .tOffset = { .iX = -iXSign, .iY = -iYSign, }, #if 0 .chAlpha = (uint8_t)( ((float)(1-iXSign) - (float)x) //!< x * ((float)(1-iYSign) - (float)y) //!< y * 256.0f ), #endif }, [1] = { .tOffset = { .iX = -iXSign + 1, .iY = -iYSign, }, .chAlpha = (uint8_t)( ((float)iXSign + (float)x) //!< x * ((float)(1-iYSign) - (float)y) //!< y * 256.0f ), }, [2] = { .tOffset = { .iX = -iXSign, .iY = -iYSign + 1, }, .chAlpha = (uint8_t)( ((float)(1-iXSign) - (float)x) //!< x * ((float)iYSign + (float)y) //!< y * 256.0f ), }, [3] = { .tOffset = { .iX = -iXSign + 1, .iY = -iYSign +1, }, .chAlpha = (uint8_t)( ((float)iXSign + (float)x) //!< x * ((float)iYSign + (float)y) //!< y * 256.0f ), }, }, }; #if 1 tResult.tMatrix[0].chAlpha = 256 - tResult.tMatrix[1].chAlpha - tResult.tMatrix[2].chAlpha - tResult.tMatrix[3].chAlpha; #endif return tResult; } __arm_2d_point_adj_alpha_t __arm_2d_point_get_adjacent_alpha_q16(arm_2d_point_fx_t *ptPoint) { assert(NULL != ptPoint); int32_t x = ptPoint->X & 0xFFFF; int32_t y = ptPoint->Y & 0xFFFF; x |= ((ptPoint->X < 0) * 0xFFFF0000); y |= ((ptPoint->Y < 0) * 0xFFFF0000); int_fast16_t iXSign = x < 0;// ? 1 : 0; int_fast16_t iYSign = y < 0;// ? 1 : 0; __arm_2d_point_adj_alpha_t tResult = { .tMatrix = { [0] = { .tOffset = { .iX = -iXSign, .iY = -iYSign, }, #if 0 .chAlpha = (uint8_t)__USAT( MUL_Q16(MUL_Q16( (TO_Q16(1-iXSign) - x) //!< x , (TO_Q16(1-iYSign) - y)) //!< y , TO_Q16(256) ) >> 16, 8), #endif }, [1] = { .tOffset = { .iX = -iXSign + 1, .iY = -iYSign, }, .chAlpha = (uint8_t)__USAT( MUL_Q16(MUL_Q16( (TO_Q16(iXSign) + x) //!< x , (TO_Q16(1-iYSign) - y)) //!< y , TO_Q16(256) ) >> 16, 8), }, [2] = { .tOffset = { .iX = -iXSign, .iY = -iYSign + 1, }, .chAlpha = (uint8_t)__USAT( MUL_Q16(MUL_Q16( (TO_Q16(1-iXSign) - x) //!< x , (TO_Q16(iYSign) + y)) //!< y , TO_Q16(256) ) >> 16, 8), }, [3] = { .tOffset = { .iX = -iXSign + 1, .iY = -iYSign +1, }, .chAlpha = (uint8_t)__USAT( MUL_Q16(MUL_Q16( (TO_Q16(iXSign) + x) //!< x , (TO_Q16(iYSign) + y)) //!< y , TO_Q16(256) ) >> 16, 8), }, }, }; #if 1 tResult.tMatrix[0].chAlpha = 256 - tResult.tMatrix[1].chAlpha - tResult.tMatrix[2].chAlpha - tResult.tMatrix[3].chAlpha; #endif return tResult; } #if __ARM_2D_CFG_FORCED_FIXED_POINT_TRANSFORM__ static void __arm_2d_transform_regression(arm_2d_size_t * __RESTRICT ptCopySize, arm_2d_location_t * pSrcPoint, float fAngle, float fScale, arm_2d_location_t * tOffset, arm_2d_location_t * center, arm_2d_rot_linear_regr_t regrCoefs[]) { #define ONE_BY_2PI_Q31 341782637.0f //#define TO_Q16(x) ((x) << 16) int_fast16_t iHeight = ptCopySize->iHeight; int_fast16_t iWidth = ptCopySize->iWidth; q31_t invHeightFx; if (1 == iHeight) { invHeightFx = 0x7fffffff; } else { invHeightFx = 0x7fffffff / (iHeight - 1); } int32_t AngleFx = lroundf(fAngle * ONE_BY_2PI_Q31); int32_t ScaleFx = (int32_t)((float)fScale * (float)TO_Q16(1)); q31_t cosAngleFx = MULTFX(arm_cos_q31(AngleFx), ScaleFx); q31_t sinAngleFx = MULTFX(arm_sin_q31(AngleFx), ScaleFx); arm_2d_point_fx_t tPointCornerFx[2][2]; arm_2d_point_fx_t centerQ16; arm_2d_point_fx_t srcPointQ16; arm_2d_point_fx_t tOffsetQ16; arm_2d_point_fx_t tmp; int32_t iXQ16, iYQ16; /* Q16 conversion */ centerQ16.X = TO_Q16(center->iX); centerQ16.Y = TO_Q16(center->iY); srcPointQ16.X = TO_Q16(pSrcPoint->iX); srcPointQ16.Y = TO_Q16(pSrcPoint->iY); tOffsetQ16.X = TO_Q16(tOffset->iX); tOffsetQ16.Y = TO_Q16(tOffset->iY); /* (0,0) corner */ tmp.X = srcPointQ16.X + 0 + tOffsetQ16.X; tmp.Y = srcPointQ16.Y + 0 + tOffsetQ16.Y; iXQ16 = tmp.X - centerQ16.X; iYQ16 = tmp.Y - centerQ16.Y; tPointCornerFx[0][0].Y = __QDADD(__QDADD(centerQ16.Y, MUL_Q16(iYQ16, cosAngleFx)), MUL_Q16(iXQ16, sinAngleFx)); tPointCornerFx[0][0].X = __QDSUB(__QDADD(centerQ16.X, MUL_Q16(iXQ16, cosAngleFx)), MUL_Q16(iYQ16, sinAngleFx)); /* ((iWidth - 1),0) corner */ tmp.X = srcPointQ16.X + 0 + tOffsetQ16.X + TO_Q16(iWidth - 1); iXQ16 = tmp.X - centerQ16.X; tPointCornerFx[1][0].Y = __QDADD(__QDADD(centerQ16.Y, MUL_Q16(iYQ16, cosAngleFx)), MUL_Q16(iXQ16, sinAngleFx)); tPointCornerFx[1][0].X = __QDSUB(__QDADD(centerQ16.X, MUL_Q16(iXQ16, cosAngleFx)), MUL_Q16(iYQ16, sinAngleFx)); /* ((iWidth - 1),(iHeight - 1)) corner */ tmp.Y = srcPointQ16.Y + tOffsetQ16.Y + TO_Q16(iHeight - 1); iYQ16 = tmp.Y - centerQ16.Y; tPointCornerFx[1][1].Y = __QDADD(__QDADD(centerQ16.Y, MUL_Q16(iYQ16, cosAngleFx)), MUL_Q16(iXQ16, sinAngleFx)); tPointCornerFx[1][1].X = __QDSUB(__QDADD(centerQ16.X, MUL_Q16(iXQ16, cosAngleFx)), MUL_Q16(iYQ16, sinAngleFx)); /* (0,(iHeight - 1)) corner */ tmp.X = srcPointQ16.X + 0 + tOffsetQ16.X; iXQ16 = tmp.X - centerQ16.X; tPointCornerFx[0][1].Y = __QDADD(__QDADD(centerQ16.Y, MUL_Q16(iYQ16, cosAngleFx)), MUL_Q16(iXQ16, sinAngleFx)); tPointCornerFx[0][1].X = __QDSUB(__QDADD(centerQ16.X, MUL_Q16(iXQ16, cosAngleFx)), MUL_Q16(iYQ16, sinAngleFx)); /* regression */ int32_t slopeXFx, slopeYFx; /* interpolation in Y direction for 1st elements column */ slopeXFx = MULTFX( (tPointCornerFx[0][1].X - tPointCornerFx[0][0].X), invHeightFx); slopeYFx = MULTFX((tPointCornerFx[0][1].Y - tPointCornerFx[0][0].Y), invHeightFx); regrCoefs[0].slopeY = slopeYFx * 2; regrCoefs[0].slopeX = slopeXFx * 2; regrCoefs[0].interceptY = tPointCornerFx[0][0].Y; regrCoefs[0].interceptX = tPointCornerFx[0][0].X; /* interpolation in Y direction for the last elements column */ slopeXFx = MULTFX( (tPointCornerFx[1][1].X - tPointCornerFx[1][0].X), invHeightFx); slopeYFx = MULTFX( (tPointCornerFx[1][1].Y - tPointCornerFx[1][0].Y), invHeightFx); regrCoefs[1].slopeY = slopeYFx* 2; regrCoefs[1].slopeX = slopeXFx* 2; regrCoefs[1].interceptY = tPointCornerFx[1][0].Y; regrCoefs[1].interceptX = tPointCornerFx[1][0].X; } #else static void __arm_2d_transform_regression(arm_2d_size_t * __RESTRICT ptCopySize, arm_2d_location_t * pSrcPoint, float fAngle, float fScale, arm_2d_location_t * tOffset, arm_2d_location_t * ptCenter, arm_2d_rot_linear_regr_t regrCoefs[]) { int_fast16_t iHeight = ptCopySize->iHeight; int_fast16_t iWidth = ptCopySize->iWidth; float invHeight; if (1 == iHeight ) { invHeight = __LARGEINVF32; } else { invHeight = 1.0f / (float) (iHeight - 1); } float cosAngle = arm_cos_f32(fAngle) * fScale; float sinAngle = arm_sin_f32(fAngle) * fScale; arm_2d_location_t tSrcPoint; arm_2d_point_float_t tPointCorner[2][2]; int16_t iX, iY; tSrcPoint.iX = pSrcPoint->iX + 0 + tOffset->iX; tSrcPoint.iY = pSrcPoint->iY + 0 + tOffset->iY; iX = tSrcPoint.iX - ptCenter->iX; iY = tSrcPoint.iY - ptCenter->iY; tPointCorner[0][0].fY = (iY * cosAngle + iX * sinAngle + ptCenter->iY); tPointCorner[0][0].fX = (-iY * sinAngle + iX * cosAngle + ptCenter->iX); tSrcPoint.iX = pSrcPoint->iX + (iWidth - 1) + tOffset->iX; iX = tSrcPoint.iX - ptCenter->iX; tPointCorner[1][0].fY = (iY * cosAngle + iX * sinAngle + ptCenter->iY); tPointCorner[1][0].fX = (-iY * sinAngle + iX * cosAngle + ptCenter->iX); tSrcPoint.iY = pSrcPoint->iY + (iHeight - 1) + tOffset->iY; iY = tSrcPoint.iY - ptCenter->iY; tPointCorner[1][1].fY = (iY * cosAngle + iX * sinAngle + ptCenter->iY); tPointCorner[1][1].fX = (-iY * sinAngle + iX * cosAngle + ptCenter->iX); tSrcPoint.iX = pSrcPoint->iX + 0 + tOffset->iX; iX = tSrcPoint.iX - ptCenter->iX; tPointCorner[0][1].fY = (iY * cosAngle + iX * sinAngle + ptCenter->iY); tPointCorner[0][1].fX = (-iY * sinAngle + iX * cosAngle + ptCenter->iX); float slopeX, slopeY; /* interpolation in Y direction for 1st elements column */ slopeX = (tPointCorner[0][1].fX - tPointCorner[0][0].fX) * invHeight; slopeY = (tPointCorner[0][1].fY - tPointCorner[0][0].fY) * invHeight; regrCoefs[0].slopeY = slopeY; regrCoefs[0].slopeX = slopeX; regrCoefs[0].interceptY = tPointCorner[0][0].fY; regrCoefs[0].interceptX = tPointCorner[0][0].fX; /* interpolation in Y direction for the last elements column */ slopeX = (tPointCorner[1][1].fX - tPointCorner[1][0].fX) * invHeight; slopeY = (tPointCorner[1][1].fY - tPointCorner[1][0].fY) * invHeight; regrCoefs[1].slopeY = slopeY; regrCoefs[1].slopeX = slopeX; regrCoefs[1].interceptY = tPointCorner[1][0].fY; regrCoefs[1].interceptX = tPointCorner[1][0].fX; } #endif ARM_NONNULL(1,2,5) static arm_2d_point_float_t *__arm_2d_transform_point( const arm_2d_location_t *ptLocation, const arm_2d_location_t *ptCenter, float fAngle, float fScale, arm_2d_point_float_t *ptOutBuffer) { int16_t iX = ptLocation->iX - ptCenter->iX; int16_t iY = ptLocation->iY - ptCenter->iY; float fX,fY; float cosAngle = arm_cos_f32(fAngle) * fScale; float sinAngle = arm_sin_f32(fAngle) * fScale; fY = (iY * cosAngle + iX * sinAngle + ptCenter->iY); fX = (-iY * sinAngle + iX * cosAngle + ptCenter->iX); #if !defined(__ARM_2D_CFG_UNSAFE_IGNORE_CALIB_IN_TRANSFORM__) if (fX > 0) { ptOutBuffer->fX = fX + __CALIB; } else { ptOutBuffer->fX = fX - __CALIB; } if (fY > 0) { ptOutBuffer->fY = fY + __CALIB; } else { ptOutBuffer->fY = fY - __CALIB; } #else ptOutBuffer->fX = fX; ptOutBuffer->fY = fY; #endif return ptOutBuffer; } static arm_2d_err_t __arm_2d_transform_preprocess_source( arm_2d_op_trans_t *ptThis, __arm_2d_transform_info_t *ptTransform) { arm_2d_tile_t *ptSource = (arm_2d_tile_t *)this.Source.ptTile; memset(ptSource, 0, sizeof(*ptSource)); ptSource->tInfo = this.Origin.ptTile->tInfo; ptSource->bIsRoot = true; ptSource->pchBuffer = NULL; //!< special case arm_2d_region_t tOrigValidRegion; if (NULL == arm_2d_tile_get_root(this.Origin.ptTile, &tOrigValidRegion, NULL)) { return ARM_2D_ERR_OUT_OF_REGION; } //! angle validation ptTransform->fAngle = fmodf(ptTransform->fAngle, ARM_2D_ANGLE(360)); if (0.0f == ptTransform->fScale) { ptTransform->fScale = 1.0f; } //! calculate the source region do { arm_2d_point_float_t tPoint; arm_2d_location_t tTopLeft = {.iX = INT16_MAX, .iY = INT16_MAX}; arm_2d_location_t tBottomRight = {.iX = INT16_MIN, .iY = INT16_MIN}; //! Top Left arm_2d_location_t tCornerPoint = tOrigValidRegion.tLocation; __arm_2d_transform_point( &tCornerPoint, &ptTransform->tCenter, ptTransform->fAngle, ptTransform->fScale, &tPoint); do { tTopLeft.iX = MIN(tTopLeft.iX, tPoint.fX); tTopLeft.iY = MIN(tTopLeft.iY, tPoint.fY); tBottomRight.iX = MAX(tBottomRight.iX, tPoint.fX); tBottomRight.iY = MAX(tBottomRight.iY, tPoint.fY); } while(0); //! Bottom Left tCornerPoint.iY += tOrigValidRegion.tSize.iHeight - 1; __arm_2d_transform_point( &tCornerPoint, &ptTransform->tCenter, ptTransform->fAngle, ptTransform->fScale, &tPoint); do { tTopLeft.iX = MIN(tTopLeft.iX, tPoint.fX); tTopLeft.iY = MIN(tTopLeft.iY, tPoint.fY); tBottomRight.iX = MAX(tBottomRight.iX, tPoint.fX); tBottomRight.iY = MAX(tBottomRight.iY, tPoint.fY); } while(0); //! Top Right tCornerPoint = tOrigValidRegion.tLocation; tCornerPoint.iX += tOrigValidRegion.tSize.iWidth - 1; __arm_2d_transform_point( &tCornerPoint, &ptTransform->tCenter, ptTransform->fAngle, ptTransform->fScale, &tPoint); do { tTopLeft.iX = MIN(tTopLeft.iX, tPoint.fX); tTopLeft.iY = MIN(tTopLeft.iY, tPoint.fY); tBottomRight.iX = MAX(tBottomRight.iX, tPoint.fX); tBottomRight.iY = MAX(tBottomRight.iY, tPoint.fY); } while(0); //! Bottom Right tCornerPoint.iY += tOrigValidRegion.tSize.iHeight - 1; __arm_2d_transform_point( &tCornerPoint, &ptTransform->tCenter, ptTransform->fAngle, ptTransform->fScale, &tPoint); do { tTopLeft.iX = MIN(tTopLeft.iX, tPoint.fX); tTopLeft.iY = MIN(tTopLeft.iY, tPoint.fY); tBottomRight.iX = MAX(tBottomRight.iX, tPoint.fX); tBottomRight.iY = MAX(tBottomRight.iY, tPoint.fY); } while(0); //! calculate the region ptTransform->tDummySourceOffset = tTopLeft; ptSource->tRegion.tSize.iHeight = tBottomRight.iY - tTopLeft.iY + 1; ptSource->tRegion.tSize.iWidth = tBottomRight.iX - tTopLeft.iX + 1; ptTransform->fScale = 1.0f / ptTransform->fScale; //ptTransform->tTargetRegion.tSize = ptSource->tRegion.tSize; } while(0); return ARM_2D_ERR_NONE; } static void __arm_2d_transform_preprocess_target( arm_2d_op_trans_t *ptThis, const arm_2d_location_t *ptTargetCentre) { __arm_2d_transform_info_t *ptTransform = (__arm_2d_transform_info_t *) ( (uintptr_t)ptThis + this.use_as__arm_2d_op_core_t.ptOp->Info.chInClassOffset); //! the following code is correct. DO NOT modify it unless you 100% sure. ptTransform->Target.tRegion.tSize = this.Source.ptTile->tRegion.tSize; #if 0 //!< please keep this code for understanding the original meaning arm_2d_region_t tTargetRegion = {0}; if (NULL != this.Target.ptRegion) { tTargetRegion = *this.Target.ptRegion; } else { tTargetRegion.tSize = this.Target.ptTile->tRegion.tSize; } #else //! equivalent code assert(NULL == this.Target.ptRegion); arm_2d_region_t tTargetRegion = { .tSize = this.Target.ptTile->tRegion.tSize, }; #endif this.Target.ptRegion = &ptTransform->Target.tRegion; ptTransform->Target.tRegion.tLocation = tTargetRegion.tLocation; //! align with the specified center point do { arm_2d_location_t tOffset = { .iX = ptTransform->tCenter.iX - ptTransform->tDummySourceOffset.iX, .iY = ptTransform->tCenter.iY - ptTransform->tDummySourceOffset.iY, }; if (NULL == ptTargetCentre) { arm_2d_location_t tTargetCenter = { .iX = tTargetRegion.tSize.iWidth >> 1, .iY = tTargetRegion.tSize.iHeight >> 1, }; tOffset.iX = tTargetCenter.iX - tOffset.iX; tOffset.iY = tTargetCenter.iY - tOffset.iY; } else { tOffset.iX = ptTargetCentre->iX - tOffset.iX; tOffset.iY = ptTargetCentre->iY - tOffset.iY; } ptTransform->Target.tRegion.tLocation.iX += tOffset.iX; ptTransform->Target.tRegion.tLocation.iY += tOffset.iY; } while(0); } ARM_NONNULL(2) arm_2d_err_t arm_2dp_gray8_tile_transform_prepare( arm_2d_op_trans_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast8_t chFillColour) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_GRAY8; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.hwColour = chFillColour; return __arm_2d_transform_preprocess_source(ptThis, &this.tTransform); } ARM_NONNULL(2) arm_2d_err_t arm_2dp_rgb565_tile_transform_prepare( arm_2d_op_trans_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast16_t hwFillColour) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_RGB565; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.hwColour = hwFillColour; return __arm_2d_transform_preprocess_source(ptThis, &this.tTransform); } ARM_NONNULL(2) arm_2d_err_t arm_2dp_cccn888_tile_transform_prepare( arm_2d_op_trans_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint32_t wFillColour) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_CCCN888; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.wColour = wFillColour; return __arm_2d_transform_preprocess_source(ptThis, &this.tTransform); } arm_fsm_rt_t __arm_2d_gray8_sw_transform(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_t, ptTask->ptOP); assert(ARM_2D_COLOUR_8BIT == OP_CORE.ptOp->Info.Colour.chScheme); __arm_2d_impl_gray8_transform( &(ptTask->Param.tCopyOrig), &this.tTransform); return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_rgb565_sw_transform(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_t, ptTask->ptOP); assert(ARM_2D_COLOUR_RGB565 == OP_CORE.ptOp->Info.Colour.chScheme); __arm_2d_impl_rgb565_transform( &(ptTask->Param.tCopyOrig), &this.tTransform); return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_cccn888_sw_transform(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_t, ptTask->ptOP); assert(ARM_2D_COLOUR_SZ_32BIT == OP_CORE.ptOp->Info.Colour.u3ColourSZ); __arm_2d_impl_cccn888_transform(&(ptTask->Param.tCopyOrig), &this.tTransform); return arm_fsm_rt_cpl; } ARM_NONNULL(2) arm_2d_err_t arm_2dp_gray8_tile_transform_with_opacity_prepare( arm_2d_op_trans_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast8_t chFillColour, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_OPACITY_GRAY8; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.chColour = chFillColour; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2) arm_2d_err_t arm_2dp_rgb565_tile_transform_with_opacity_prepare( arm_2d_op_trans_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast16_t hwFillColour, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_OPACITY_RGB565; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.hwColour = hwFillColour; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2) arm_2d_err_t arm_2dp_cccn888_tile_transform_with_opacity_prepare( arm_2d_op_trans_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_location_t tCentre, float fAngle, float fScale, uint32_t wFillColour, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptOP); if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_OPACITY_CCCN888; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; this.tTransform.Mask.wColour = wFillColour; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } arm_fsm_rt_t __arm_2d_gray8_sw_transform_with_alpha(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_GRAY8 == OP_CORE.ptOp->Info.Colour.chScheme); if (255 == this.chOpacity) { __arm_2d_impl_gray8_transform( &(ptTask->Param.tCopyOrig), &this.tTransform); } else { __arm_2d_impl_gray8_transform_with_opacity( &(ptTask->Param.tCopyOrig), &this.tTransform, this.chOpacity); } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_rgb565_sw_transform_with_alpha(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_RGB565 == OP_CORE.ptOp->Info.Colour.chScheme); if (255 == this.chOpacity) { __arm_2d_impl_rgb565_transform( &(ptTask->Param.tCopyOrig), &this.tTransform); } else { __arm_2d_impl_rgb565_transform_with_opacity( &(ptTask->Param.tCopyOrig), &this.tTransform, this.chOpacity); } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_cccn888_sw_transform_with_alpha(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_SZ_32BIT == OP_CORE.ptOp->Info.Colour.u3ColourSZ); if (255 == this.chOpacity) { __arm_2d_impl_cccn888_transform(&(ptTask->Param.tCopyOrig), &this.tTransform); } else { __arm_2d_impl_cccn888_transform_with_opacity( &(ptTask->Param.tCopyOrig), &this.tTransform, this.chOpacity); } return arm_fsm_rt_cpl; } ARM_NONNULL(2) arm_fsm_rt_t arm_2dp_tile_transform(arm_2d_op_trans_t *ptOP, const arm_2d_tile_t *ptTarget, const arm_2d_region_t *ptRegion, const arm_2d_location_t *ptTargetCentre) { assert(NULL != ptTarget); ARM_2D_IMPL(arm_2d_op_trans_t, ptOP); arm_2d_location_t tTargetCentre; if (!__arm_2d_op_acquire((arm_2d_op_core_t *)ptThis)) { return arm_fsm_rt_on_going; } if (NULL != ptRegion) { __arm_2d_transform_info_t *ptTransform = (__arm_2d_transform_info_t *) ( (uintptr_t)ptThis + this.use_as__arm_2d_op_core_t.ptOp->Info.chInClassOffset); this.Target.ptTile = arm_2d_tile_generate_child( ptTarget, ptRegion, &ptTransform->Target.tTile, false); if (NULL == this.Target.ptTile) { arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION; if (ARM_2D_RUNTIME_FEATURE.TREAT_OUT_OF_RANGE_AS_COMPLETE) { tResult = arm_fsm_rt_cpl; } return __arm_2d_op_depose((arm_2d_op_core_t *)ptThis, tResult); } if (NULL != ptTargetCentre) { tTargetCentre.iX = ptTargetCentre->iX - ptRegion->tLocation.iX; tTargetCentre.iY = ptTargetCentre->iY - ptRegion->tLocation.iY; ptTargetCentre = &tTargetCentre; } } else { this.Target.ptTile = ptTarget; //this.Target.ptRegion = ptRegion; } this.Target.ptRegion = NULL; __arm_2d_transform_preprocess_target( ptThis, ptTargetCentre); return __arm_2d_op_invoke((arm_2d_op_core_t *)ptThis); } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_gray8_tile_transform_with_src_mask_prepare( arm_2d_op_trans_msk_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_GRAY8; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = chFillColour; this.Mask.ptOriginSide = ptSourceMask; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_rgb565_tile_transform_with_src_mask_prepare( arm_2d_op_trans_msk_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_RGB565; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = hwFillColour; this.Mask.ptOriginSide = ptSourceMask; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_cccn888_tile_transform_with_src_mask_prepare( arm_2d_op_trans_msk_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_CCCN888; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = wFillColour; this.Mask.ptOriginSide = ptSourceMask; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } arm_fsm_rt_t __arm_2d_gray8_sw_transform_with_src_mask(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptTask->ptOP); assert(ARM_2D_COLOUR_8BIT == OP_CORE.ptOp->Info.Colour.chScheme); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); if (bIsMaskChannel8In32) { __arm_2d_impl_gray8_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_gray8_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_rgb565_sw_transform_with_src_mask(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptTask->ptOP); assert(ARM_2D_COLOUR_RGB565 == OP_CORE.ptOp->Info.Colour.chScheme); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); if (bIsMaskChannel8In32) { __arm_2d_impl_rgb565_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_rgb565_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_cccn888_sw_transform_with_src_mask(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_t, ptTask->ptOP); assert(ARM_2D_COLOUR_SZ_32BIT == OP_CORE.ptOp->Info.Colour.u3ColourSZ); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); if (bIsMaskChannel8In32) { __arm_2d_impl_cccn888_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_cccn888_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } return arm_fsm_rt_cpl; } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_gray8_tile_transform_with_src_mask_and_opacity_prepare( arm_2d_op_trans_msk_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_GRAY8; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = chFillColour; this.Mask.ptOriginSide = ptSourceMask; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_rgb565_tile_transform_with_src_mask_and_opacity_prepare( arm_2d_op_trans_msk_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_RGB565; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = hwFillColour; this.Mask.ptOriginSide = ptSourceMask; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } ARM_NONNULL(2,3) arm_2d_err_t arm_2dp_cccn888_tile_transform_with_src_mask_and_opacity_prepare( arm_2d_op_trans_msk_opa_t *ptOP, const arm_2d_tile_t *ptSource, const arm_2d_tile_t *ptSourceMask, const arm_2d_location_t tCentre, float fAngle, float fScale, uint_fast8_t chOpacity) { assert(NULL != ptSource); ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptOP); arm_2d_err_t tErr = __arm_mask_validate(ptSource, ptSourceMask, NULL, NULL, 0); if (tErr < 0) { return tErr; } if (!arm_2d_op_wait_async((arm_2d_op_core_t *)ptThis)) { return ARM_2D_ERR_BUSY; } OP_CORE.ptOp = &ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_CCCN888; this.Source.ptTile = &this.Origin.tDummySource; this.Origin.ptTile = ptSource; this.wMode = 0; this.tTransform.fAngle = fAngle; this.tTransform.fScale = fScale; this.tTransform.tCenter = tCentre; //this.tTransform.Mask.hwColour = wFillColour; this.Mask.ptOriginSide = ptSourceMask; this.chOpacity = chOpacity; return __arm_2d_transform_preprocess_source((arm_2d_op_trans_t *)ptThis, &this.tTransform); } arm_fsm_rt_t __arm_2d_gray8_sw_transform_with_src_mask_and_opacity(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_8BIT == OP_CORE.ptOp->Info.Colour.chScheme); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); #endif if (255 == this.chOpacity) { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_gray8_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_gray8_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } } else { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_gray8_transform_with_src_chn_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } else #endif { __arm_2d_impl_gray8_transform_with_src_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_rgb565_sw_transform_with_src_mask_and_opacity(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_RGB565 == OP_CORE.ptOp->Info.Colour.chScheme); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); #endif if (255 == this.chOpacity) { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_rgb565_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_rgb565_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } } else { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_rgb565_transform_with_src_chn_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } else #endif { __arm_2d_impl_rgb565_transform_with_src_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } } return arm_fsm_rt_cpl; } arm_fsm_rt_t __arm_2d_cccn888_sw_transform_with_src_mask_and_opacity(__arm_2d_sub_task_t *ptTask) { ARM_2D_IMPL(arm_2d_op_trans_msk_opa_t, ptTask->ptOP); assert(ARM_2D_COLOUR_SZ_32BIT == OP_CORE.ptOp->Info.Colour.u3ColourSZ); #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ bool bIsMaskChannel8In32 = (ARM_2D_CHANNEL_8in32 == ptTask->Param.tCopyOrigMask.tOrigMask.tColour.chScheme); #endif if (255 == this.chOpacity) { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_cccn888_transform_with_src_chn_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } else #endif { __arm_2d_impl_cccn888_transform_with_src_mask( &(ptTask->Param.tCopyOrigMask), &this.tTransform); } } else { #if __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__ if (bIsMaskChannel8In32) { __arm_2d_impl_cccn888_transform_with_src_chn_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } else #endif { __arm_2d_impl_cccn888_transform_with_src_mask_and_opacity( &(ptTask->Param.tCopyOrigMask), &this.tTransform, this.chOpacity); } } return arm_fsm_rt_cpl; } /*----------------------------------------------------------------------------* * Accelerable Low Level APIs * *----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------* * Draw a point whose cordinates is stored as float point. * *----------------------------------------------------------------------------*/ #if 0 static arm_2d_region_t *__arm_2d_calculate_region( const arm_2d_point_float_t *ptLocation, arm_2d_region_t *ptRegion) { assert(NULL != ptLocation); assert(NULL != ptRegion); /* +-----+-----+ * | P0 | P1 | * +---- p ----+ * | P2 | -- | * +-----+-----+ */ arm_2d_location_t tPoints[3]; tPoints[0].iX = (int16_t)ptLocation->fX; tPoints[2].iX = (int16_t)ptLocation->fX; tPoints[1].iX = (int16_t)(ptLocation->fX + 0.99f); ptRegion->tSize.iWidth = tPoints[1].iX - tPoints[0].iX + 1; tPoints[0].iY = (int16_t)ptLocation->fY; tPoints[2].iY = (int16_t)ptLocation->fY; tPoints[1].iY = (int16_t)(ptLocation->fY + 0.99f); ptRegion->tSize.iHeight = tPoints[2].iY - tPoints[0].iY + 1; ptRegion->tLocation = tPoints[0]; return ptRegion; } #endif /*----------------------------------------------------------------------------* * Low Level IO Interfaces * *----------------------------------------------------------------------------*/ __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_GRAY8, __arm_2d_gray8_sw_transform); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_RGB565, __arm_2d_rgb565_sw_transform); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_CCCN888, __arm_2d_cccn888_sw_transform); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_GRAY8, __arm_2d_gray8_sw_transform_with_alpha); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_RGB565, __arm_2d_rgb565_sw_transform_with_alpha); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_CCCN888, __arm_2d_cccn888_sw_transform_with_alpha); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_GRAY8, __arm_2d_gray8_sw_transform_with_src_mask); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_RGB565, __arm_2d_rgb565_sw_transform_with_src_mask); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_CCCN888, __arm_2d_cccn888_sw_transform_with_src_mask); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_GRAY8, __arm_2d_gray8_sw_transform_with_src_mask_and_opacity); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_RGB565, __arm_2d_rgb565_sw_transform_with_src_mask_and_opacity); __WEAK def_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_CCCN888, __arm_2d_cccn888_sw_transform_with_src_mask_and_opacity); const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_GRAY8 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_8BIT, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM, .chInClassOffset = offsetof(arm_2d_op_trans_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_GRAY8), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_RGB565 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_RGB565, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM, .chInClassOffset = offsetof(arm_2d_op_trans_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_RGB565), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_CCCN888 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_CCCN888, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM, .chInClassOffset = offsetof(arm_2d_op_trans_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_CCCN888), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_OPACITY_GRAY8 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_GRAY8, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_GRAY8), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_OPACITY_RGB565 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_RGB565, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_RGB565), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_OPACITY_CCCN888 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_CCCN888, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_ALPHA_CCCN888), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_GRAY8 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_8BIT, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK, .chInClassOffset = offsetof(arm_2d_op_trans_msk_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_GRAY8), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_RGB565 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_RGB565, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK, .chInClassOffset = offsetof(arm_2d_op_trans_msk_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_RGB565), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_CCCN888 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_CCCN888, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK, .chInClassOffset = offsetof(arm_2d_op_trans_msk_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_CCCN888), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_GRAY8 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_8BIT, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK_AND_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_msk_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_GRAY8), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_RGB565 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_RGB565, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK_AND_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_msk_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_RGB565), .ptFillOrigLike = NULL, }, }, }; const __arm_2d_op_info_t ARM_2D_OP_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_CCCN888 = { .Info = { .Colour = { .chScheme = ARM_2D_COLOUR_CCCN888, }, .Param = { .bHasSource = true, .bHasOrigin = true, .bHasTarget = true, .bHasSrcMask = true, }, .chOpIndex = __ARM_2D_OP_IDX_TRANSFORM_WITH_SOURCE_MASK_AND_OPACITY, .chInClassOffset = offsetof(arm_2d_op_trans_msk_opa_t, tTransform), .LowLevelIO = { .ptCopyOrigLike = ref_low_lv_io(__ARM_2D_IO_TRANSFORM_WITH_SRC_MSK_AND_OPACITY_CCCN888), .ptFillOrigLike = NULL, }, }, }; #ifdef __cplusplus } #endif