diff -r 352185384b8a -r a4b63488e0b0 graphicscomposition/openwfcompositionengine/common/src/owfimage.c --- a/graphicscomposition/openwfcompositionengine/common/src/owfimage.c Fri Apr 23 15:29:19 2010 +0100 +++ b/graphicscomposition/openwfcompositionengine/common/src/owfimage.c Fri Apr 23 17:57:02 2010 +0100 @@ -211,7 +211,7 @@ OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL); OWF_ASSERT(image->width >= 3 && image->height >= 3); - copyStride = image->width * image->pixelSize; + copyStride = OWF_Image_GetStride(image->width, &image->format, 0); /* top side replication */ srcPtr = (OWFuint8*) image->data; @@ -252,11 +252,15 @@ void* srcLinePtr; OWFpixel* dstLinePtr; OWFboolean replicateEdges = OWF_FALSE; +#ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + OWFint widthBytes; +#endif OWF_ASSERT(dst != 0 && dst->data != NULL); OWF_ASSERT(src != 0 && src->data != NULL); OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL); + OWF_ASSERT(dst->stride == OWF_Image_GetStride(dst->width, &dst->format, 0)); srcLinePtr = src->data; dstLinePtr = (OWFpixel*) dst->data; @@ -285,6 +289,10 @@ return OWF_FALSE; } +#ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + widthBytes = OWF_Image_GetStride(src->width, &src->format, 0); +#endif + for (countY = src->height; countY; countY--) { OWFint count = src->width; @@ -294,7 +302,7 @@ { case OWF_IMAGE_ARGB8888: { -#ifdef USE_FLOAT_PIXEL +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT OWFuint32* srcPtr = (OWFuint32*) srcLinePtr; while (count > 0) @@ -312,7 +320,7 @@ count--; } #else - memcpy(dstLinePtr, srcLinePtr, src->stride); + memcpy(dstLinePtr, srcLinePtr, widthBytes); #endif break; } @@ -323,7 +331,7 @@ while (count > 0) { -#ifdef USE_FLOAT_PIXEL +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT dstPtr->color.alpha = OWF_FULLY_OPAQUE; dstPtr->color.red = (OWFsubpixel) OWF_RED_MAX_VALUE * ((*srcPtr & ARGB8888_RED_MASK) >> ARGB8888_RED_SHIFT) / OWF_BYTE_MAX_VALUE; @@ -370,6 +378,7 @@ } break; } +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT case OWF_IMAGE_UYVY: { OWFuint8* srcPtr = (OWFuint8*) srcLinePtr; @@ -412,7 +421,7 @@ } break; } - +#endif default: { return OWF_FALSE; /* source format not supported */ @@ -501,10 +510,14 @@ OWFuint32* dstPtr; OWFpixel* srcPtr; OWFuint8* destination; +#ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + OWFint widthBytes; +#endif OWF_ASSERT(dst != 0 && dst->data != NULL); OWF_ASSERT(src != 0 && src->data != NULL); OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL); + /* Note: src->stride cannot be relied upon to be correct. Assume lines are contiguous. */ if (src->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL) { @@ -530,6 +543,10 @@ } destination = (OWFuint8*) dst->data; +#ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + widthBytes = OWF_Image_GetStride(src->width, &src->format, 0); +#endif + for (countY = 0; countY < src->height; countY++) { dstPtr = (OWFuint32*) destination; @@ -539,7 +556,7 @@ { case OWF_IMAGE_ARGB8888: { -#ifdef USE_FLOAT_PIXEL +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT OWFint countX; OWFuint32 dstPixel = 0; @@ -558,20 +575,20 @@ srcPtr ++; } #else - memcpy(dstPtr, srcPtr, src->stride); - srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + src->stride); + memcpy(dstPtr, srcPtr, widthBytes); + srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + widthBytes); #endif break; } case OWF_IMAGE_XRGB8888: { -#ifdef USE_FLOAT_PIXEL OWFint countX; OWFuint32 dstPixel = 0; for (countX = 0; countX < src->width; countX++) { +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT dstPixel = ARGB8888_ALPHA_MASK; dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.red / OWF_RED_MAX_VALUE)) << ARGB8888_RED_SHIFT); @@ -579,16 +596,17 @@ ARGB8888_GREEN_SHIFT); dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.blue / OWF_BLUE_MAX_VALUE)) << ARGB8888_BLUE_SHIFT); +#else + dstPixel = *(OWFuint32*)srcPtr | ARGB8888_ALPHA_MASK; +#endif *dstPtr = dstPixel; dstPtr ++; srcPtr ++; } -#else - memcpy(dstPtr, srcPtr, src->stride); - srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + src->stride); -#endif break; } +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + /* TODO: Fix this code! It should be converting from ARGB into YUV, not the other way around. */ case OWF_IMAGE_UYVY: { OWFuint8* srcPtr = (OWFuint8*) srcLinePtr; @@ -631,6 +649,7 @@ } break; } +#endif default: { @@ -1223,10 +1242,12 @@ OWF_ASSERT(image != 0); OWF_ASSERT(image->data != 0); OWF_ASSERT(image->format.pixelFormat == OWF_IMAGE_ARGB_INTERNAL); + /* Note: image->stride cannot be relied upon to be correct. Assume lines are contiguous. */ numPixels = image->width * image->height; pixels = (OWFpixel*) image->data; +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT for (i = 0; i < numPixels; i++) { pixels[i].color.red = (OWFsubpixel) red; @@ -1234,6 +1255,29 @@ pixels[i].color.blue = (OWFsubpixel) blue; pixels[i].color.alpha = (OWFsubpixel) alpha; } +#else + if (alpha == red && alpha == green && alpha == blue) + { + /* If all four bytes are the same, just use memset */ + OWFuint32 clearBytes = numPixels * sizeof(OWFuint32); + + memset(pixels, alpha, clearBytes); + } + else + { + /* Otherwise assign each pixel the packed value */ + OWFuint32* pixelPtr = (OWFuint32*)pixels; + OWFuint32 pixel; + + pixel = (alpha << ARGB8888_ALPHA_SHIFT) | (red << ARGB8888_RED_SHIFT) | + (green << ARGB8888_GREEN_SHIFT) | (blue << ARGB8888_BLUE_SHIFT); + + for (i = 0; i < numPixels; i++) + { + pixelPtr[i] = pixel; + } + } +#endif } /*----------------------------------------------------------------------------*/ @@ -1500,25 +1544,9 @@ OWFint rowCount = drect.height; \ while (rowCount > 0) { \ OWFint colCount = drect.width; \ - while (colCount > 0) { \ - if (!(blend->tsColor && COLOR_MATCH(SC, TSC))) \ - { \ + while (colCount > 0) { #define BLENDER_INNER_LOOP_END \ - DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \ - } /* end tsColor check */ \ - srcPtr ++; \ - dstPtr ++; \ - --colCount; \ - } \ - srcPtr += srcLineDelta; \ - dstPtr += dstLineDelta; \ - --rowCount; \ - } - -#define BLENDER_INNER_LOOP_END_WITH_MASK \ - DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \ - } /* end tsColor check */ \ srcPtr ++; \ dstPtr ++; \ maskPtr++; \ @@ -1529,14 +1557,16 @@ maskPtr += maskLineDelta; \ --rowCount; \ } - -#define TSC blend->tsColor->color -#define SC srcPtr->color - -/* Note: actually would be better to compare integer values - * for TSC match -> eliminate float arithmetic pitfalls - */ -#define COLOR_MATCH(x, y) (x.red==y.red && x.green==y.green && x.blue==y.blue) + +#define BLENDER_INNER_LOOP_END_NO_MASK \ + srcPtr ++; \ + dstPtr ++; \ + --colCount; \ + } \ + srcPtr += srcLineDelta; \ + dstPtr += dstLineDelta; \ + --rowCount; \ + } #define SA srcPtr->color.alpha #define SR srcPtr->color.red @@ -1653,11 +1683,6 @@ srcLineDelta = src->width - srect.width; dstLineDelta = dst->width - drect.width; - if ((transparency & OWF_TRANSPARENCY_GLOBAL_ALPHA) && (GA > (OWF_ALPHA_MAX_VALUE - OWF_ALPHA_MIN_STEP_VALUE))) - { - /* Fully opaque, so ignore global alpha */ - transparency &= ~OWF_TRANSPARENCY_GLOBAL_ALPHA; - } /* inner loops */ switch (transparency) { @@ -1673,7 +1698,7 @@ DG = SG; DB = SB; DA = OWF_FULLY_OPAQUE; - BLENDER_INNER_LOOP_END; + BLENDER_INNER_LOOP_END_NO_MASK; #else memcpy(dstPtr, srcPtr, drect.height*drect.width*4); #endif @@ -1695,40 +1720,57 @@ OWF_ALPHA_MAX_VALUE; DA = GA + (DA * (OWF_FULLY_OPAQUE - GA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; - BLENDER_INNER_LOOP_END; + BLENDER_INNER_LOOP_END_NO_MASK; break; } case OWF_TRANSPARENCY_SOURCE_ALPHA: { +#ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + OWFuint32 redBlueMask = (ARGB8888_RED_MASK | ARGB8888_BLUE_MASK); + OWFuint32 alphaGreenMask = (ARGB8888_ALPHA_MASK | ARGB8888_GREEN_MASK); + OWFuint32 halfRedBlue = 0x00800080; +#endif /* rgb = src.rgb + dst.rgb * (1 - src.alpha) alpha = src.alpha + dst.alpha * (1 - src.alpha) */ BLENDER_INNER_LOOP_BEGIN; - if (SA > (OWF_ALPHA_MAX_VALUE - OWF_ALPHA_MIN_STEP_VALUE)) +#ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT + DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; + DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; + DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; + DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; +#else + { + OWFuint32 srcP = *(OWFuint32*)srcPtr; + OWFuint8 srcA = srcP >> ARGB8888_ALPHA_SHIFT; + + if (srcA == OWF_ALPHA_MAX_VALUE) { /* Fully opaque source pixel */ - DR = SR; - DG = SG; - DB = SB; - DA = OWF_FULLY_OPAQUE; + *(OWFuint32*)dstPtr = srcP; } else { - if (SA >= OWF_ALPHA_MIN_STEP_VALUE) + if (srcA) { - /* Not fully transparent source pixel */ - /* - * DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; - */ - DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8; - DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8; - DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8; - DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8; + /* Not fully transparent source pixel. Algorithm after Jim Blinn */ + OWFuint32 mask = 0xFF - srcA; + OWFuint32 dstP = *(OWFuint32*)dstPtr; + OWFuint32 blend; + + blend = mask * (dstP & redBlueMask) + halfRedBlue; + srcP += ((blend + ((blend >> 8) & redBlueMask) >> 8)) & redBlueMask; + blend = mask * ((dstP >> 8) & redBlueMask) + halfRedBlue; + srcP += (blend + ((blend >> 8) & redBlueMask)) & alphaGreenMask; + + *(OWFuint32*)dstPtr = srcP; } } - BLENDER_INNER_LOOP_END; + } +#endif + BLENDER_INNER_LOOP_END_NO_MASK; break; } @@ -1747,7 +1789,7 @@ OWF_ALPHA_MAX_VALUE; DA = MA + (DA * (OWF_FULLY_OPAQUE - MA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; - BLENDER_INNER_LOOP_END_WITH_MASK; + BLENDER_INNER_LOOP_END; break; } @@ -1769,7 +1811,7 @@ OWF_ALPHA_MAX_VALUE; DA = SAEA + (DA * (OWF_FULLY_OPAQUE - SAEA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE; - BLENDER_INNER_LOOP_END; + BLENDER_INNER_LOOP_END_NO_MASK; break; } @@ -1793,7 +1835,7 @@ OWF_ALPHA_MAX_VALUE; //No need to check with OWF_ALPHA_MIN_VALUE as it is zero OWF_ASSERT(GA <= OWF_ALPHA_MAX_VALUE); - BLENDER_INNER_LOOP_END_WITH_MASK; + BLENDER_INNER_LOOP_END; break; } @@ -1876,12 +1918,12 @@ case OWF_IMAGE_RGB565: case OWF_IMAGE_L16: + case OWF_IMAGE_UYVY: { return 2; } case OWF_IMAGE_L8: - case OWF_IMAGE_UYVY: { return 1; } @@ -1917,6 +1959,7 @@ case OWF_IMAGE_ARGB8888: case OWF_IMAGE_XRGB8888: case OWF_IMAGE_L32: + case OWF_IMAGE_UYVY: { padding = 4; break; @@ -1937,7 +1980,6 @@ } case OWF_IMAGE_L8: - case OWF_IMAGE_UYVY: { padding = 1; break;