graphicscomposition/openwfcompositionengine/common/src/owfimage.c
branchNewGraphicsArchitecture
changeset 39 a4b63488e0b0
parent 35 3aa07f06a4b7
child 61 4ac0d9f65e95
equal deleted inserted replaced
38:352185384b8a 39:a4b63488e0b0
   209     
   209     
   210     OWF_ASSERT(image);
   210     OWF_ASSERT(image);
   211     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   211     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   212     OWF_ASSERT(image->width >= 3 && image->height >= 3);
   212     OWF_ASSERT(image->width >= 3 && image->height >= 3);
   213     
   213     
   214     copyStride = image->width * image->pixelSize;    
   214     copyStride = OWF_Image_GetStride(image->width, &image->format, 0);
   215     
   215     
   216     /* top side replication */
   216     /* top side replication */
   217     srcPtr = (OWFuint8*) image->data;
   217     srcPtr = (OWFuint8*) image->data;
   218     srcPtr += 1 * image->stride + 0 * image->pixelSize;
   218     srcPtr += 1 * image->stride + 0 * image->pixelSize;
   219     dstPtr = (OWFuint8*) image->data;
   219     dstPtr = (OWFuint8*) image->data;
   250 {
   250 {
   251     OWFint      countY, widthDiff, heightDiff;
   251     OWFint      countY, widthDiff, heightDiff;
   252     void*       srcLinePtr;
   252     void*       srcLinePtr;
   253     OWFpixel*   dstLinePtr;
   253     OWFpixel*   dstLinePtr;
   254     OWFboolean  replicateEdges = OWF_FALSE;
   254     OWFboolean  replicateEdges = OWF_FALSE;
       
   255 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   256     OWFint      widthBytes;
       
   257 #endif
   255     
   258     
   256 
   259 
   257     OWF_ASSERT(dst != 0 && dst->data != NULL);
   260     OWF_ASSERT(dst != 0 && dst->data != NULL);
   258     OWF_ASSERT(src != 0 && src->data != NULL);
   261     OWF_ASSERT(src != 0 && src->data != NULL);
   259     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   262     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
       
   263     OWF_ASSERT(dst->stride == OWF_Image_GetStride(dst->width, &dst->format, 0));
   260     
   264     
   261     srcLinePtr = src->data;
   265     srcLinePtr = src->data;
   262     dstLinePtr = (OWFpixel*) dst->data;    
   266     dstLinePtr = (OWFpixel*) dst->data;    
   263     
   267     
   264     /* dst image must either be the same size as the src image or 2 pixels 
   268     /* dst image must either be the same size as the src image or 2 pixels 
   283     if (dst->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   287     if (dst->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   284     {
   288     {
   285         return OWF_FALSE;
   289         return OWF_FALSE;
   286     }
   290     }
   287 
   291 
       
   292 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   293     widthBytes = OWF_Image_GetStride(src->width, &src->format, 0);
       
   294 #endif
       
   295 
   288     for (countY = src->height; countY; countY--)
   296     for (countY = src->height; countY; countY--)
   289     {
   297     {
   290         OWFint count = src->width;
   298         OWFint count = src->width;
   291         OWFpixel* dstPtr = dstLinePtr;
   299         OWFpixel* dstPtr = dstLinePtr;
   292     
   300     
   293         switch (src->format.pixelFormat)
   301         switch (src->format.pixelFormat)
   294         {
   302         {
   295             case OWF_IMAGE_ARGB8888:
   303             case OWF_IMAGE_ARGB8888:
   296             {
   304             {
   297 #ifdef USE_FLOAT_PIXEL
   305 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   298                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   306                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   299     
   307     
   300                 while (count > 0)
   308                 while (count > 0)
   301                 {
   309                 {
   302                     dstPtr->color.alpha = (OWFsubpixel)
   310                     dstPtr->color.alpha = (OWFsubpixel)
   310                     dstPtr ++;
   318                     dstPtr ++;
   311                     srcPtr ++;
   319                     srcPtr ++;
   312                     count--;
   320                     count--;
   313                 }
   321                 }
   314 #else
   322 #else
   315                 memcpy(dstLinePtr, srcLinePtr, src->stride);
   323                 memcpy(dstLinePtr, srcLinePtr, widthBytes);
   316 #endif
   324 #endif
   317                 break;
   325                 break;
   318             }
   326             }
   319     
   327     
   320             case OWF_IMAGE_XRGB8888:
   328             case OWF_IMAGE_XRGB8888:
   321             {
   329             {
   322                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   330                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   323                 
   331                 
   324                 while (count > 0)
   332                 while (count > 0)
   325                 {
   333                 {
   326 #ifdef USE_FLOAT_PIXEL
   334 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   327                     dstPtr->color.alpha = OWF_FULLY_OPAQUE;
   335                     dstPtr->color.alpha = OWF_FULLY_OPAQUE;
   328                     dstPtr->color.red   = (OWFsubpixel)
   336                     dstPtr->color.red   = (OWFsubpixel)
   329                         OWF_RED_MAX_VALUE * ((*srcPtr & ARGB8888_RED_MASK) >> ARGB8888_RED_SHIFT) / OWF_BYTE_MAX_VALUE;
   337                         OWF_RED_MAX_VALUE * ((*srcPtr & ARGB8888_RED_MASK) >> ARGB8888_RED_SHIFT) / OWF_BYTE_MAX_VALUE;
   330                     dstPtr->color.green = (OWFsubpixel)
   338                     dstPtr->color.green = (OWFsubpixel)
   331                         OWF_GREEN_MAX_VALUE * ((*srcPtr & ARGB8888_GREEN_MASK) >> ARGB8888_GREEN_SHIFT) / OWF_BYTE_MAX_VALUE;
   339                         OWF_GREEN_MAX_VALUE * ((*srcPtr & ARGB8888_GREEN_MASK) >> ARGB8888_GREEN_SHIFT) / OWF_BYTE_MAX_VALUE;
   368                     srcPtr ++;
   376                     srcPtr ++;
   369                     count--;
   377                     count--;
   370                 }
   378                 }
   371                 break;
   379                 break;
   372             }
   380             }
       
   381 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   373             case OWF_IMAGE_UYVY:
   382             case OWF_IMAGE_UYVY:
   374             {
   383             {
   375                 OWFuint8* srcPtr = (OWFuint8*) srcLinePtr;
   384                 OWFuint8* srcPtr = (OWFuint8*) srcLinePtr;
   376                 OWFint y,u,v,r,g,b,x;
   385                 OWFint y,u,v,r,g,b,x;
   377                 for (x = 0; x < count; x++)
   386                 for (x = 0; x < count; x++)
   410                     dstPtr++;                  
   419                     dstPtr++;                  
   411                     srcPtr += 4;                                      
   420                     srcPtr += 4;                                      
   412                 }
   421                 }
   413                 break;
   422                 break;
   414             }
   423             }
   415                 
   424 #endif     
   416             default:
   425             default:
   417             {
   426             {
   418                 return OWF_FALSE; /* source format not supported */
   427                 return OWF_FALSE; /* source format not supported */
   419             }
   428             }
   420         }
   429         }
   499 {
   508 {
   500     OWFint                  countY;
   509     OWFint                  countY;
   501     OWFuint32*              dstPtr;
   510     OWFuint32*              dstPtr;
   502     OWFpixel*               srcPtr;
   511     OWFpixel*               srcPtr;
   503     OWFuint8*               destination;
   512     OWFuint8*               destination;
       
   513 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   514     OWFint                  widthBytes;
       
   515 #endif
   504 
   516 
   505     OWF_ASSERT(dst != 0 && dst->data != NULL);
   517     OWF_ASSERT(dst != 0 && dst->data != NULL);
   506     OWF_ASSERT(src != 0 && src->data != NULL);
   518     OWF_ASSERT(src != 0 && src->data != NULL);
   507     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   519     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
       
   520     /* Note: src->stride cannot be relied upon to be correct. Assume lines are contiguous. */
   508 
   521 
   509     if (src->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   522     if (src->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   510     {
   523     {
   511         return OWF_FALSE;
   524         return OWF_FALSE;
   512     }
   525     }
   528     {
   541     {
   529         OWF_Image_UnpremultiplyAlpha(src);
   542         OWF_Image_UnpremultiplyAlpha(src);
   530     }
   543     }
   531 
   544 
   532     destination = (OWFuint8*) dst->data;
   545     destination = (OWFuint8*) dst->data;
       
   546 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   547     widthBytes = OWF_Image_GetStride(src->width, &src->format, 0);
       
   548 #endif
       
   549 
   533     for (countY = 0; countY < src->height; countY++)
   550     for (countY = 0; countY < src->height; countY++)
   534     {   
   551     {   
   535         dstPtr = (OWFuint32*) destination;    
   552         dstPtr = (OWFuint32*) destination;    
   536         destination += dst->stride;
   553         destination += dst->stride;
   537 
   554 
   538         switch (dst->format.pixelFormat)
   555         switch (dst->format.pixelFormat)
   539         {
   556         {
   540             case OWF_IMAGE_ARGB8888:
   557             case OWF_IMAGE_ARGB8888:
   541             {
   558             {
   542 #ifdef USE_FLOAT_PIXEL
   559 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   543                 OWFint countX;
   560                 OWFint countX;
   544                 OWFuint32 dstPixel = 0;               
   561                 OWFuint32 dstPixel = 0;               
   545                 
   562                 
   546                 for (countX = 0; countX < src->width; countX++)
   563                 for (countX = 0; countX < src->width; countX++)
   547                 {
   564                 {
   556                     *dstPtr = dstPixel;
   573                     *dstPtr = dstPixel;
   557                     dstPtr ++;
   574                     dstPtr ++;
   558                     srcPtr ++;
   575                     srcPtr ++;
   559                 }
   576                 }
   560 #else
   577 #else
   561                 memcpy(dstPtr, srcPtr, src->stride);
   578                 memcpy(dstPtr, srcPtr, widthBytes);
   562                 srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + src->stride);
   579                 srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + widthBytes);
   563 #endif
   580 #endif
   564                 break;
   581                 break;
   565             }
   582             }
   566     
   583     
   567             case OWF_IMAGE_XRGB8888:
   584             case OWF_IMAGE_XRGB8888:
   568             {
   585             {
   569 #ifdef USE_FLOAT_PIXEL
       
   570                 OWFint countX;
   586                 OWFint countX;
   571                 OWFuint32 dstPixel = 0;
   587                 OWFuint32 dstPixel = 0;
   572                 
   588                 
   573                 for (countX = 0; countX < src->width; countX++)
   589                 for (countX = 0; countX < src->width; countX++)
   574                 {
   590                 {
       
   591 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   575                     dstPixel  = ARGB8888_ALPHA_MASK;
   592                     dstPixel  = ARGB8888_ALPHA_MASK;
   576                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.red / OWF_RED_MAX_VALUE))   <<
   593                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.red / OWF_RED_MAX_VALUE))   <<
   577                                 ARGB8888_RED_SHIFT);
   594                                 ARGB8888_RED_SHIFT);
   578                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.green / OWF_GREEN_MAX_VALUE)) <<
   595                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.green / OWF_GREEN_MAX_VALUE)) <<
   579                                 ARGB8888_GREEN_SHIFT);
   596                                 ARGB8888_GREEN_SHIFT);
   580                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.blue / OWF_BLUE_MAX_VALUE))  <<
   597                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.blue / OWF_BLUE_MAX_VALUE))  <<
   581                                 ARGB8888_BLUE_SHIFT);
   598                                 ARGB8888_BLUE_SHIFT);
       
   599 #else
       
   600                     dstPixel = *(OWFuint32*)srcPtr | ARGB8888_ALPHA_MASK;
       
   601 #endif
   582                     *dstPtr = dstPixel;
   602                     *dstPtr = dstPixel;
   583                     dstPtr ++;
   603                     dstPtr ++;
   584                     srcPtr ++;
   604                     srcPtr ++;
   585                 }
   605                 }
   586 #else
       
   587                 memcpy(dstPtr, srcPtr, src->stride);
       
   588                 srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + src->stride);
       
   589 #endif
       
   590                 break;
   606                 break;
   591             }
   607             }
       
   608 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   609 			/* TODO: Fix this code! It should be converting from ARGB into YUV, not the other way around. */
   592             case OWF_IMAGE_UYVY:
   610             case OWF_IMAGE_UYVY:
   593             {
   611             {
   594                 OWFuint8* srcPtr = (OWFuint8*) srcLinePtr;
   612                 OWFuint8* srcPtr = (OWFuint8*) srcLinePtr;
   595                 OWFint y,u,v,r,g,b,x;
   613                 OWFint y,u,v,r,g,b,x;
   596                 for (x = 0; x < count; x++)
   614                 for (x = 0; x < count; x++)
   629                     dstPtr++;                  
   647                     dstPtr++;                  
   630                     srcPtr += 4;                                      
   648                     srcPtr += 4;                                      
   631                 }
   649                 }
   632                 break;
   650                 break;
   633             }
   651             }
       
   652 #endif
   634                 
   653                 
   635             default:
   654             default:
   636             {
   655             {
   637                 return OWF_FALSE; /* destination format not supported */
   656                 return OWF_FALSE; /* destination format not supported */
   638             }
   657             }
  1221     OWFpixel*                pixels;
  1240     OWFpixel*                pixels;
  1222 
  1241 
  1223     OWF_ASSERT(image != 0);
  1242     OWF_ASSERT(image != 0);
  1224     OWF_ASSERT(image->data != 0);
  1243     OWF_ASSERT(image->data != 0);
  1225     OWF_ASSERT(image->format.pixelFormat == OWF_IMAGE_ARGB_INTERNAL);
  1244     OWF_ASSERT(image->format.pixelFormat == OWF_IMAGE_ARGB_INTERNAL);
       
  1245     /* Note: image->stride cannot be relied upon to be correct. Assume lines are contiguous. */
  1226 
  1246 
  1227     numPixels = image->width * image->height;
  1247     numPixels = image->width * image->height;
  1228     pixels = (OWFpixel*) image->data;
  1248     pixels = (OWFpixel*) image->data;
  1229 
  1249 
       
  1250 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
  1230     for (i = 0; i < numPixels; i++)
  1251     for (i = 0; i < numPixels; i++)
  1231     {
  1252     {
  1232         pixels[i].color.red   = (OWFsubpixel) red;
  1253         pixels[i].color.red   = (OWFsubpixel) red;
  1233         pixels[i].color.green = (OWFsubpixel) green;
  1254         pixels[i].color.green = (OWFsubpixel) green;
  1234         pixels[i].color.blue  = (OWFsubpixel) blue;
  1255         pixels[i].color.blue  = (OWFsubpixel) blue;
  1235         pixels[i].color.alpha = (OWFsubpixel) alpha;
  1256         pixels[i].color.alpha = (OWFsubpixel) alpha;
  1236     }
  1257     }
       
  1258 #else
       
  1259     if (alpha == red && alpha == green && alpha == blue)
       
  1260         {
       
  1261         /* If all four bytes are the same, just use memset */
       
  1262         OWFuint32 clearBytes = numPixels * sizeof(OWFuint32);
       
  1263 
       
  1264         memset(pixels, alpha, clearBytes);
       
  1265         }
       
  1266     else
       
  1267         {
       
  1268         /* Otherwise assign each pixel the packed value */
       
  1269         OWFuint32* pixelPtr = (OWFuint32*)pixels;
       
  1270         OWFuint32 pixel;
       
  1271     
       
  1272         pixel = (alpha << ARGB8888_ALPHA_SHIFT) | (red << ARGB8888_RED_SHIFT) |
       
  1273                 (green << ARGB8888_GREEN_SHIFT) | (blue << ARGB8888_BLUE_SHIFT);
       
  1274 
       
  1275         for (i = 0; i < numPixels; i++)
       
  1276             {
       
  1277             pixelPtr[i] = pixel;
       
  1278             }
       
  1279         }
       
  1280 #endif
  1237 }
  1281 }
  1238 
  1282 
  1239 /*----------------------------------------------------------------------------*/
  1283 /*----------------------------------------------------------------------------*/
  1240 OWF_API_CALL void
  1284 OWF_API_CALL void
  1241 OWF_Image_PremultiplyAlpha(OWF_IMAGE* image)
  1285 OWF_Image_PremultiplyAlpha(OWF_IMAGE* image)
  1498 /*----------------------------------------------------------------------------*/
  1542 /*----------------------------------------------------------------------------*/
  1499 #define BLENDER_INNER_LOOP_BEGIN \
  1543 #define BLENDER_INNER_LOOP_BEGIN \
  1500     OWFint rowCount = drect.height; \
  1544     OWFint rowCount = drect.height; \
  1501     while (rowCount > 0) { \
  1545     while (rowCount > 0) { \
  1502         OWFint colCount = drect.width; \
  1546         OWFint colCount = drect.width; \
  1503         while (colCount > 0) { \
  1547         while (colCount > 0) {
  1504             if (!(blend->tsColor && COLOR_MATCH(SC, TSC))) \
       
  1505             { \
       
  1506 
  1548 
  1507 #define BLENDER_INNER_LOOP_END \
  1549 #define BLENDER_INNER_LOOP_END \
  1508                 DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \
       
  1509             } /* end tsColor check */ \
       
  1510             srcPtr ++; \
       
  1511             dstPtr ++; \
       
  1512             --colCount; \
       
  1513         } \
       
  1514         srcPtr += srcLineDelta; \
       
  1515         dstPtr += dstLineDelta; \
       
  1516         --rowCount; \
       
  1517     }
       
  1518 
       
  1519 #define BLENDER_INNER_LOOP_END_WITH_MASK \
       
  1520                 DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \
       
  1521             } /* end tsColor check */ \
       
  1522             srcPtr ++; \
  1550             srcPtr ++; \
  1523             dstPtr ++; \
  1551             dstPtr ++; \
  1524             maskPtr++; \
  1552             maskPtr++; \
  1525             --colCount; \
  1553             --colCount; \
  1526         } \
  1554         } \
  1527         srcPtr += srcLineDelta; \
  1555         srcPtr += srcLineDelta; \
  1528         dstPtr += dstLineDelta; \
  1556         dstPtr += dstLineDelta; \
  1529         maskPtr += maskLineDelta; \
  1557         maskPtr += maskLineDelta; \
  1530         --rowCount; \
  1558         --rowCount; \
  1531     }
  1559     }
  1532 
  1560 	
  1533 #define TSC blend->tsColor->color
  1561 #define BLENDER_INNER_LOOP_END_NO_MASK \
  1534 #define SC srcPtr->color
  1562             srcPtr ++; \
  1535 
  1563             dstPtr ++; \
  1536 /* Note: actually would be better to compare integer values
  1564             --colCount; \
  1537  * for TSC match -> eliminate float arithmetic pitfalls
  1565         } \
  1538  */
  1566         srcPtr += srcLineDelta; \
  1539 #define COLOR_MATCH(x, y) (x.red==y.red && x.green==y.green && x.blue==y.blue)
  1567         dstPtr += dstLineDelta; \
       
  1568         --rowCount; \
       
  1569     }
  1540 
  1570 
  1541 #define SA srcPtr->color.alpha
  1571 #define SA srcPtr->color.alpha
  1542 #define SR srcPtr->color.red
  1572 #define SR srcPtr->color.red
  1543 #define SG srcPtr->color.green
  1573 #define SG srcPtr->color.green
  1544 #define SB srcPtr->color.blue
  1574 #define SB srcPtr->color.blue
  1651         maskLineDelta = 0;
  1681         maskLineDelta = 0;
  1652     }
  1682     }
  1653     srcLineDelta = src->width - srect.width;
  1683     srcLineDelta = src->width - srect.width;
  1654     dstLineDelta = dst->width - drect.width;
  1684     dstLineDelta = dst->width - drect.width;
  1655 
  1685 
  1656     if ((transparency & OWF_TRANSPARENCY_GLOBAL_ALPHA) && (GA > (OWF_ALPHA_MAX_VALUE - OWF_ALPHA_MIN_STEP_VALUE)))
       
  1657         {
       
  1658         /* Fully opaque, so ignore global alpha */
       
  1659         transparency &= ~OWF_TRANSPARENCY_GLOBAL_ALPHA;
       
  1660         }
       
  1661     /* inner loops */
  1686     /* inner loops */
  1662     switch (transparency)
  1687     switch (transparency)
  1663     {
  1688     {
  1664         case OWF_TRANSPARENCY_NONE:
  1689         case OWF_TRANSPARENCY_NONE:
  1665         {
  1690         {
  1671             BLENDER_INNER_LOOP_BEGIN;
  1696             BLENDER_INNER_LOOP_BEGIN;
  1672                 DR = SR;
  1697                 DR = SR;
  1673                 DG = SG;
  1698                 DG = SG;
  1674                 DB = SB;
  1699                 DB = SB;
  1675                 DA = OWF_FULLY_OPAQUE;
  1700                 DA = OWF_FULLY_OPAQUE;
  1676             BLENDER_INNER_LOOP_END;
  1701             BLENDER_INNER_LOOP_END_NO_MASK;
  1677 #else
  1702 #else
  1678             memcpy(dstPtr, srcPtr, drect.height*drect.width*4);
  1703             memcpy(dstPtr, srcPtr, drect.height*drect.width*4);
  1679 #endif
  1704 #endif
  1680             break;
  1705             break;
  1681         }
  1706         }
  1693                      OWF_ALPHA_MAX_VALUE;
  1718                      OWF_ALPHA_MAX_VALUE;
  1694                 DB = (SB * GA + DB * (OWF_FULLY_OPAQUE - GA) + OWF_BLEND_ROUNDING_VALUE) /
  1719                 DB = (SB * GA + DB * (OWF_FULLY_OPAQUE - GA) + OWF_BLEND_ROUNDING_VALUE) /
  1695                      OWF_ALPHA_MAX_VALUE;
  1720                      OWF_ALPHA_MAX_VALUE;
  1696                 DA = GA + (DA * (OWF_FULLY_OPAQUE - GA) + OWF_BLEND_ROUNDING_VALUE) / 
  1721                 DA = GA + (DA * (OWF_FULLY_OPAQUE - GA) + OWF_BLEND_ROUNDING_VALUE) / 
  1697                      OWF_ALPHA_MAX_VALUE;
  1722                      OWF_ALPHA_MAX_VALUE;
  1698             BLENDER_INNER_LOOP_END;
  1723             BLENDER_INNER_LOOP_END_NO_MASK;
  1699             break;
  1724             break;
  1700         }
  1725         }
  1701 
  1726 
  1702         case OWF_TRANSPARENCY_SOURCE_ALPHA:
  1727         case OWF_TRANSPARENCY_SOURCE_ALPHA:
  1703         {
  1728         {
       
  1729 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
  1730         OWFuint32 redBlueMask = (ARGB8888_RED_MASK | ARGB8888_BLUE_MASK);
       
  1731         OWFuint32 alphaGreenMask = (ARGB8888_ALPHA_MASK | ARGB8888_GREEN_MASK);
       
  1732         OWFuint32 halfRedBlue = 0x00800080;
       
  1733 #endif
  1704             /*
  1734             /*
  1705             rgb     = src.rgb + dst.rgb * (1 - src.alpha)
  1735             rgb     = src.rgb + dst.rgb * (1 - src.alpha)
  1706             alpha    = src.alpha + dst.alpha * (1 - src.alpha)
  1736             alpha    = src.alpha + dst.alpha * (1 - src.alpha)
  1707             */
  1737             */
  1708             BLENDER_INNER_LOOP_BEGIN;
  1738             BLENDER_INNER_LOOP_BEGIN;
  1709                 if (SA > (OWF_ALPHA_MAX_VALUE - OWF_ALPHA_MIN_STEP_VALUE))
  1739 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
  1740             DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1741             DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1742             DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1743             DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1744 #else
       
  1745             {
       
  1746                 OWFuint32 srcP = *(OWFuint32*)srcPtr;
       
  1747                 OWFuint8 srcA = srcP >> ARGB8888_ALPHA_SHIFT;
       
  1748 
       
  1749                 if (srcA == OWF_ALPHA_MAX_VALUE)
  1710                     {
  1750                     {
  1711                     /* Fully opaque source pixel */
  1751                     /* Fully opaque source pixel */
  1712                     DR = SR;
  1752                     *(OWFuint32*)dstPtr = srcP;
  1713                     DG = SG;
       
  1714                     DB = SB;
       
  1715                     DA = OWF_FULLY_OPAQUE;
       
  1716                     }
  1753                     }
  1717                 else
  1754                 else
  1718                     {
  1755                     {
  1719                     if (SA >= OWF_ALPHA_MIN_STEP_VALUE)
  1756                     if (srcA)
  1720                         {
  1757                         {
  1721                         /* Not fully transparent source pixel */
  1758                         /* Not fully transparent source pixel. Algorithm after Jim Blinn */
  1722                        /*
  1759                         OWFuint32 mask = 0xFF - srcA;
  1723                         * DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1760                         OWFuint32 dstP = *(OWFuint32*)dstPtr;
  1724                         */ 
  1761                         OWFuint32 blend;
  1725                         DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8;
  1762 
  1726                         DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8;
  1763                         blend = mask * (dstP & redBlueMask) + halfRedBlue;
  1727                         DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8;
  1764                         srcP += ((blend + ((blend >> 8) & redBlueMask) >> 8)) & redBlueMask;
  1728                         DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) >> 8;
  1765                         blend = mask * ((dstP >> 8) & redBlueMask) + halfRedBlue;
       
  1766                         srcP += (blend + ((blend >> 8) & redBlueMask)) & alphaGreenMask;
       
  1767 
       
  1768                         *(OWFuint32*)dstPtr = srcP;
  1729                         }
  1769                         }
  1730                     }
  1770                     }
  1731             BLENDER_INNER_LOOP_END;
  1771             }
       
  1772 #endif
       
  1773             BLENDER_INNER_LOOP_END_NO_MASK;
  1732             break;
  1774             break;
  1733         }
  1775         }
  1734 
  1776 
  1735         case OWF_TRANSPARENCY_MASK:
  1777         case OWF_TRANSPARENCY_MASK:
  1736         {
  1778         {
  1745                      OWF_ALPHA_MAX_VALUE;
  1787                      OWF_ALPHA_MAX_VALUE;
  1746                 DB = (SB * MA + DB * (OWF_FULLY_OPAQUE - MA) + OWF_BLEND_ROUNDING_VALUE) /
  1788                 DB = (SB * MA + DB * (OWF_FULLY_OPAQUE - MA) + OWF_BLEND_ROUNDING_VALUE) /
  1747                      OWF_ALPHA_MAX_VALUE;
  1789                      OWF_ALPHA_MAX_VALUE;
  1748                 DA = MA + (DA * (OWF_FULLY_OPAQUE - MA) + OWF_BLEND_ROUNDING_VALUE) / 
  1790                 DA = MA + (DA * (OWF_FULLY_OPAQUE - MA) + OWF_BLEND_ROUNDING_VALUE) / 
  1749                      OWF_ALPHA_MAX_VALUE;
  1791                      OWF_ALPHA_MAX_VALUE;
  1750             BLENDER_INNER_LOOP_END_WITH_MASK;
  1792             BLENDER_INNER_LOOP_END;
  1751             break;
  1793             break;
  1752         }
  1794         }
  1753 
  1795 
  1754         case OWF_TRANSPARENCY_GLOBAL_ALPHA | OWF_TRANSPARENCY_SOURCE_ALPHA:
  1796         case OWF_TRANSPARENCY_GLOBAL_ALPHA | OWF_TRANSPARENCY_SOURCE_ALPHA:
  1755         {
  1797         {
  1767                      OWF_ALPHA_MAX_VALUE;
  1809                      OWF_ALPHA_MAX_VALUE;
  1768                 DB = (SB * GA + DB * (OWF_FULLY_OPAQUE - SAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1810                 DB = (SB * GA + DB * (OWF_FULLY_OPAQUE - SAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1769                      OWF_ALPHA_MAX_VALUE;
  1811                      OWF_ALPHA_MAX_VALUE;
  1770                 DA = SAEA + (DA * (OWF_FULLY_OPAQUE - SAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1812                 DA = SAEA + (DA * (OWF_FULLY_OPAQUE - SAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1771                          OWF_ALPHA_MAX_VALUE;
  1813                          OWF_ALPHA_MAX_VALUE;
  1772             BLENDER_INNER_LOOP_END;
  1814             BLENDER_INNER_LOOP_END_NO_MASK;
  1773             break;
  1815             break;
  1774         }
  1816         }
  1775 
  1817 
  1776         case OWF_TRANSPARENCY_GLOBAL_ALPHA | OWF_TRANSPARENCY_MASK:
  1818         case OWF_TRANSPARENCY_GLOBAL_ALPHA | OWF_TRANSPARENCY_MASK:
  1777         {
  1819         {
  1791                      OWF_ALPHA_MAX_VALUE;
  1833                      OWF_ALPHA_MAX_VALUE;
  1792                 DA = MAEA + (DA * (OWF_FULLY_OPAQUE - MAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1834                 DA = MAEA + (DA * (OWF_FULLY_OPAQUE - MAEA) + OWF_BLEND_ROUNDING_VALUE) /
  1793                      OWF_ALPHA_MAX_VALUE;
  1835                      OWF_ALPHA_MAX_VALUE;
  1794                 //No need to check with OWF_ALPHA_MIN_VALUE as it is zero
  1836                 //No need to check with OWF_ALPHA_MIN_VALUE as it is zero
  1795                 OWF_ASSERT(GA <= OWF_ALPHA_MAX_VALUE);
  1837                 OWF_ASSERT(GA <= OWF_ALPHA_MAX_VALUE);
  1796             BLENDER_INNER_LOOP_END_WITH_MASK;
  1838             BLENDER_INNER_LOOP_END;
  1797             break;
  1839             break;
  1798         }
  1840         }
  1799 
  1841 
  1800         default:
  1842         default:
  1801         {
  1843         {
  1874             return 3;
  1916             return 3;
  1875         }
  1917         }
  1876 
  1918 
  1877         case OWF_IMAGE_RGB565:
  1919         case OWF_IMAGE_RGB565:
  1878         case OWF_IMAGE_L16:
  1920         case OWF_IMAGE_L16:
       
  1921         case OWF_IMAGE_UYVY:
  1879         {
  1922         {
  1880             return 2;
  1923             return 2;
  1881         }
  1924         }
  1882 
  1925 
  1883         case OWF_IMAGE_L8:
  1926         case OWF_IMAGE_L8:
  1884         case OWF_IMAGE_UYVY:
       
  1885         {
  1927         {
  1886             return 1;
  1928             return 1;
  1887         }
  1929         }
  1888 
  1930 
  1889         case OWF_IMAGE_L1:
  1931         case OWF_IMAGE_L1:
  1915         }
  1957         }
  1916 
  1958 
  1917         case OWF_IMAGE_ARGB8888:
  1959         case OWF_IMAGE_ARGB8888:
  1918         case OWF_IMAGE_XRGB8888:
  1960         case OWF_IMAGE_XRGB8888:
  1919         case OWF_IMAGE_L32:
  1961         case OWF_IMAGE_L32:
       
  1962         case OWF_IMAGE_UYVY:
  1920         {
  1963         {
  1921             padding = 4;
  1964             padding = 4;
  1922             break;
  1965             break;
  1923         }
  1966         }
  1924 
  1967 
  1935             padding = 2;
  1978             padding = 2;
  1936             break;
  1979             break;
  1937         }
  1980         }
  1938 
  1981 
  1939         case OWF_IMAGE_L8:
  1982         case OWF_IMAGE_L8:
  1940         case OWF_IMAGE_UYVY:
       
  1941         {
  1983         {
  1942             padding = 1;
  1984             padding = 1;
  1943             break;
  1985             break;
  1944         }
  1986         }
  1945 
  1987