graphicscomposition/openwfcompositionengine/common/src/owfimage.c
changeset 152 9f1c3fea0f87
parent 36 01a6848ebfd7
equal deleted inserted replaced
111:29ddb8a72f0e 152:9f1c3fea0f87
     1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
     1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
     2  *
     2  * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
       
     3  * 
     3  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * copy of this software and/or associated documentation files (the
     5  * copy of this software and/or associated documentation files (the
     5  * "Materials"), to deal in the Materials without restriction, including
     6  * "Materials"), to deal in the Materials without restriction, including
     6  * without limitation the rights to use, copy, modify, merge, publish,
     7  * without limitation the rights to use, copy, modify, merge, publish,
     7  * distribute, sublicense, and/or sell copies of the Materials, and to
     8  * distribute, sublicense, and/or sell copies of the Materials, and to
    46 
    47 
    47 /*----------------------------------------------------------------------------*/
    48 /*----------------------------------------------------------------------------*/
    48 OWF_API_CALL void
    49 OWF_API_CALL void
    49 OWF_IMAGE_Ctor(void* self)
    50 OWF_IMAGE_Ctor(void* self)
    50 {
    51 {
       
    52     DPRINT(("OWF_IMAGE_Ctor"));
       
    53 
    51     self = self;
    54     self = self;
    52 }
    55 }
    53 
    56 
    54 /*----------------------------------------------------------------------------*/
    57 /*----------------------------------------------------------------------------*/
    55 OWF_API_CALL void
    58 OWF_API_CALL void
    56 OWF_IMAGE_Dtor(void* self)
    59 OWF_IMAGE_Dtor(void* self)
    57 {
    60 {
    58     OWF_IMAGE* image;
    61     OWF_IMAGE* image;
    59 
    62 
       
    63     DPRINT(("OWF_IMAGE_Dtor"));
       
    64 
    60     image = (OWF_IMAGE*)self;
    65     image = (OWF_IMAGE*)self;
    61 
    66 
    62     if (image && image->data)
    67     if (image && image->data)
    63     {
    68     {
    64         if (!image->foreign)
    69         if (!image->foreign)
    99 OWF_API_CALL void
   104 OWF_API_CALL void
   100 OWF_Image_NonLinearizeData(OWF_IMAGE* image)\
   105 OWF_Image_NonLinearizeData(OWF_IMAGE* image)\
   101 {
   106 {
   102     OWFpixel*            ptr;
   107     OWFpixel*            ptr;
   103     OWFint               count;
   108     OWFint               count;
       
   109 
       
   110     DPRINT(("OWF_Image_NonLinearizeData"));
   104 
   111 
   105     OWF_ASSERT(image != NULL && image->data != NULL);
   112     OWF_ASSERT(image != NULL && image->data != NULL);
   106     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   113     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   107 
   114 
   108     if (!image->format.linear)
   115     if (!image->format.linear)
   134 OWF_Image_LinearizeData(OWF_IMAGE* image)
   141 OWF_Image_LinearizeData(OWF_IMAGE* image)
   135 {
   142 {
   136     OWFpixel*               ptr;
   143     OWFpixel*               ptr;
   137     OWFuint                 count;
   144     OWFuint                 count;
   138 
   145 
       
   146     DPRINT(("OWF_Image_LinearizeData"));
       
   147 
   139     OWF_ASSERT(image != NULL && image->data != NULL);
   148     OWF_ASSERT(image != NULL && image->data != NULL);
   140     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   149     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   141 
   150 
   142     if (image->format.linear)
   151     if (image->format.linear)
   143     {
   152     {
   171 OWF_Image_Gamma(OWF_IMAGE* image, OWFfloat gamma)
   180 OWF_Image_Gamma(OWF_IMAGE* image, OWFfloat gamma)
   172 {
   181 {
   173     OWFpixel*            ptr;
   182     OWFpixel*            ptr;
   174     OWFint               count;
   183     OWFint               count;
   175 
   184 
       
   185     DPRINT(("OWF_Image_Gamma"));
       
   186 
   176     OWF_ASSERT(image != NULL && image->data != NULL);
   187     OWF_ASSERT(image != NULL && image->data != NULL);
   177     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   188     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   178 
   189 
   179     if (gamma == 1.0f)
   190     if (gamma == 1.0f)
   180     {
   191     {
   205     OWFint          y;
   216     OWFint          y;
   206     OWFint          copyStride;
   217     OWFint          copyStride;
   207     OWFuint8*       srcPtr      = NULL;
   218     OWFuint8*       srcPtr      = NULL;
   208     OWFuint8*       dstPtr      = NULL;
   219     OWFuint8*       dstPtr      = NULL;
   209     
   220     
       
   221     DPRINT(("OWF_Image_EdgeReplication"));
       
   222 
   210     OWF_ASSERT(image);
   223     OWF_ASSERT(image);
   211     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   224     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   212     OWF_ASSERT(image->width >= 3 && image->height >= 3);
   225     OWF_ASSERT(image->width >= 3 && image->height >= 3);
   213     
   226     
   214     copyStride = image->width * image->pixelSize;    
   227     copyStride = OWF_Image_GetStride(image->width, &image->format, 0);
   215     
   228     
   216     /* top side replication */
   229     /* top side replication */
   217     srcPtr = (OWFuint8*) image->data;
   230     srcPtr = (OWFuint8*) image->data;
   218     srcPtr += 1 * image->stride + 0 * image->pixelSize;
   231     srcPtr += 1 * image->stride + 0 * image->pixelSize;
   219     dstPtr = (OWFuint8*) image->data;
   232     dstPtr = (OWFuint8*) image->data;
   250 {
   263 {
   251     OWFint      countY, widthDiff, heightDiff;
   264     OWFint      countY, widthDiff, heightDiff;
   252     void*       srcLinePtr;
   265     void*       srcLinePtr;
   253     OWFpixel*   dstLinePtr;
   266     OWFpixel*   dstLinePtr;
   254     OWFboolean  replicateEdges = OWF_FALSE;
   267     OWFboolean  replicateEdges = OWF_FALSE;
   255     
   268 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   269     OWFint      widthBytes;
       
   270 #endif
       
   271 
       
   272     DPRINT(("OWF_Image_SourceFormatConversion"));
   256 
   273 
   257     OWF_ASSERT(dst != 0 && dst->data != NULL);
   274     OWF_ASSERT(dst != 0 && dst->data != NULL);
   258     OWF_ASSERT(src != 0 && src->data != NULL);
   275     OWF_ASSERT(src != 0 && src->data != NULL);
   259     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   276     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
       
   277     OWF_ASSERT(dst->stride == OWF_Image_GetStride(dst->width, &dst->format, 0));
   260     
   278     
   261     srcLinePtr = src->data;
   279     srcLinePtr = src->data;
   262     dstLinePtr = (OWFpixel*) dst->data;    
   280     dstLinePtr = (OWFpixel*) dst->data;    
   263     
   281     
   264     /* dst image must either be the same size as the src image or 2 pixels 
   282     /* dst image must either be the same size as the src image or 2 pixels 
   283     if (dst->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   301     if (dst->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   284     {
   302     {
   285         return OWF_FALSE;
   303         return OWF_FALSE;
   286     }
   304     }
   287 
   305 
       
   306 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   307     widthBytes = OWF_Image_GetStride(src->width, &src->format, 0);
       
   308 #endif
       
   309 
   288     for (countY = src->height; countY; countY--)
   310     for (countY = src->height; countY; countY--)
   289     {
   311     {
   290         OWFint count = src->width;
   312         OWFint count = src->width;
   291         OWFpixel* dstPtr = dstLinePtr;
   313         OWFpixel* dstPtr = dstLinePtr;
   292     
   314     
   293         switch (src->format.pixelFormat)
   315         switch (src->format.pixelFormat)
   294         {
   316         {
   295             case OWF_IMAGE_ARGB8888:
   317             case OWF_IMAGE_ARGB8888:
   296             {
   318             {
       
   319 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   297                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   320                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   298     
   321     
   299                 while (count > 0)
   322                 while (count > 0)
   300                 {
   323                 {
   301                     dstPtr->color.alpha = (OWFsubpixel)
   324                     dstPtr->color.alpha = (OWFsubpixel)
   308                         OWF_BLUE_MAX_VALUE * ((*srcPtr & ARGB8888_BLUE_MASK) >> ARGB8888_BLUE_SHIFT) / OWF_BYTE_MAX_VALUE;
   331                         OWF_BLUE_MAX_VALUE * ((*srcPtr & ARGB8888_BLUE_MASK) >> ARGB8888_BLUE_SHIFT) / OWF_BYTE_MAX_VALUE;
   309                     dstPtr ++;
   332                     dstPtr ++;
   310                     srcPtr ++;
   333                     srcPtr ++;
   311                     count--;
   334                     count--;
   312                 }
   335                 }
       
   336 #else
       
   337                 memcpy(dstLinePtr, srcLinePtr, widthBytes);
       
   338 #endif
   313                 break;
   339                 break;
   314             }
   340             }
   315     
   341     
   316             case OWF_IMAGE_XRGB8888:
   342             case OWF_IMAGE_XRGB8888:
   317             {
   343             {
   318                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   344                 OWFuint32* srcPtr = (OWFuint32*) srcLinePtr;
   319                 
   345                 
   320                 while (count > 0)
   346                 while (count > 0)
   321                 {
   347                 {
       
   348 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   322                     dstPtr->color.alpha = OWF_FULLY_OPAQUE;
   349                     dstPtr->color.alpha = OWF_FULLY_OPAQUE;
   323                     dstPtr->color.red   = (OWFsubpixel)
   350                     dstPtr->color.red   = (OWFsubpixel)
   324                         OWF_RED_MAX_VALUE * ((*srcPtr & ARGB8888_RED_MASK) >> ARGB8888_RED_SHIFT) / OWF_BYTE_MAX_VALUE;
   351                         OWF_RED_MAX_VALUE * ((*srcPtr & ARGB8888_RED_MASK) >> ARGB8888_RED_SHIFT) / OWF_BYTE_MAX_VALUE;
   325                     dstPtr->color.green = (OWFsubpixel)
   352                     dstPtr->color.green = (OWFsubpixel)
   326                         OWF_GREEN_MAX_VALUE * ((*srcPtr & ARGB8888_GREEN_MASK) >> ARGB8888_GREEN_SHIFT) / OWF_BYTE_MAX_VALUE;
   353                         OWF_GREEN_MAX_VALUE * ((*srcPtr & ARGB8888_GREEN_MASK) >> ARGB8888_GREEN_SHIFT) / OWF_BYTE_MAX_VALUE;
   327                     dstPtr->color.blue  = (OWFsubpixel)
   354                     dstPtr->color.blue  = (OWFsubpixel)
   328                         OWF_BLUE_MAX_VALUE * ((*srcPtr & ARGB8888_BLUE_MASK) >> ARGB8888_BLUE_SHIFT) / OWF_BYTE_MAX_VALUE;
   355                         OWF_BLUE_MAX_VALUE * ((*srcPtr & ARGB8888_BLUE_MASK) >> ARGB8888_BLUE_SHIFT) / OWF_BYTE_MAX_VALUE;
       
   356 #else
       
   357                     *(OWFuint32*)dstPtr = *srcPtr | ARGB8888_ALPHA_MASK;
       
   358 #endif
   329                     dstPtr ++;
   359                     dstPtr ++;
   330                     srcPtr ++;
   360                     srcPtr ++;
   331                     count--;
   361                     count--;
   332                 }
   362                 }
   333                 break;
   363                 break;
   386 OWF_Image_GetStride(OWFint width, const OWF_IMAGE_FORMAT* format, OWFint minimumStride)
   416 OWF_Image_GetStride(OWFint width, const OWF_IMAGE_FORMAT* format, OWFint minimumStride)
   387 {
   417 {
   388     OWFint                  size;
   418     OWFint                  size;
   389     OWFint                  pixelSize;
   419     OWFint                  pixelSize;
   390 
   420 
       
   421     DPRINT(("OWF_Image_GetStride"));
       
   422 
   391     OWF_ASSERT(format);
   423     OWF_ASSERT(format);
   392 
   424 
   393     pixelSize = OWF_Image_GetFormatPixelSize(format->pixelFormat);
   425     pixelSize = OWF_Image_GetFormatPixelSize(format->pixelFormat);
   394 
   426 
   395     if (pixelSize < 0)
   427     if (pixelSize < 0)
   418 
   450 
   419 /*----------------------------------------------------------------------------*/
   451 /*----------------------------------------------------------------------------*/
   420 OWF_API_CALL OWFboolean
   452 OWF_API_CALL OWFboolean
   421 OWF_Image_IsValidDestinationFormat(OWF_IMAGE_FORMAT* format)
   453 OWF_Image_IsValidDestinationFormat(OWF_IMAGE_FORMAT* format)
   422 {
   454 {
       
   455     DPRINT(("OWF_Image_IsValidDestinationFormat"));
       
   456 
   423     switch (format->pixelFormat)
   457     switch (format->pixelFormat)
   424     {
   458     {
   425         case OWF_IMAGE_ARGB8888:
   459         case OWF_IMAGE_ARGB8888:
   426         {
   460         {
   427             return OWF_TRUE;
   461             return OWF_TRUE;
   448 OWF_Image_DestinationFormatConversion(OWF_IMAGE* dst, OWF_IMAGE* src)
   482 OWF_Image_DestinationFormatConversion(OWF_IMAGE* dst, OWF_IMAGE* src)
   449 {
   483 {
   450     OWFint                  countY;
   484     OWFint                  countY;
   451     OWFuint32*              dstPtr;
   485     OWFuint32*              dstPtr;
   452     OWFpixel*               srcPtr;
   486     OWFpixel*               srcPtr;
       
   487 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   488     OWFint                  widthBytes;
       
   489 #endif
       
   490 
       
   491     DPRINT(("OWF_Image_DestinationFormatConversion"));
   453 
   492 
   454     OWF_ASSERT(dst != 0 && dst->data != NULL);
   493     OWF_ASSERT(dst != 0 && dst->data != NULL);
   455     OWF_ASSERT(src != 0 && src->data != NULL);
   494     OWF_ASSERT(src != 0 && src->data != NULL);
   456     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   495     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
       
   496     /* Note: src->stride cannot be relied upon to be correct. Assume lines are contiguous. */
   457 
   497 
   458     if (src->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   498     if (src->format.pixelFormat != OWF_IMAGE_ARGB_INTERNAL)
   459     {
   499     {
   460         return OWF_FALSE;
   500         return OWF_FALSE;
   461     }
   501     }
   475     }
   515     }
   476     else if (!dst->format.premultiplied && src->format.premultiplied)
   516     else if (!dst->format.premultiplied && src->format.premultiplied)
   477     {
   517     {
   478         OWF_Image_UnpremultiplyAlpha(src);
   518         OWF_Image_UnpremultiplyAlpha(src);
   479     }
   519     }
       
   520 
       
   521 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
   522     widthBytes = OWF_Image_GetStride(src->width, &src->format, 0);
       
   523 #endif
   480 
   524 
   481     for (countY = 0; countY < src->height; countY++)
   525     for (countY = 0; countY < src->height; countY++)
   482     {   
   526     {   
   483         OWFuint8* destination = (OWFuint8*) dst->data;
   527         OWFuint8* destination = (OWFuint8*) dst->data;
   484         destination += countY*dst->stride;
   528         destination += countY*dst->stride;
   486     
   530     
   487         switch (dst->format.pixelFormat)
   531         switch (dst->format.pixelFormat)
   488         {
   532         {
   489             case OWF_IMAGE_ARGB8888:
   533             case OWF_IMAGE_ARGB8888:
   490             {
   534             {
       
   535 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   491                 OWFint countX;
   536                 OWFint countX;
   492                 OWFuint32 dstPixel = 0;               
   537                 OWFuint32 dstPixel = 0;               
   493                 
   538                 
   494                 for (countX = 0; countX < src->width; countX++)
   539                 for (countX = 0; countX < src->width; countX++)
   495                 {
   540                 {
   503                                 ARGB8888_BLUE_SHIFT);
   548                                 ARGB8888_BLUE_SHIFT);
   504                     *dstPtr = dstPixel;
   549                     *dstPtr = dstPixel;
   505                     dstPtr ++;
   550                     dstPtr ++;
   506                     srcPtr ++;
   551                     srcPtr ++;
   507                 }
   552                 }
       
   553 #else
       
   554                 memcpy(dstPtr, srcPtr, widthBytes);
       
   555                 srcPtr = (OWFpixel*)((OWFuint8*)srcPtr + widthBytes);
       
   556 #endif
   508                 break;
   557                 break;
   509             }
   558             }
   510     
   559     
   511             case OWF_IMAGE_XRGB8888:
   560             case OWF_IMAGE_XRGB8888:
   512             {
   561             {
   513                 OWFint countX;
   562                 OWFint countX;
   514                 OWFuint32 dstPixel = 0;
   563                 OWFuint32 dstPixel = 0;
   515                 
   564                 
   516                 for (countX = 0; countX < src->width; countX++)
   565                 for (countX = 0; countX < src->width; countX++)
   517                 {
   566                 {
       
   567 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   518                     dstPixel  = ARGB8888_ALPHA_MASK;
   568                     dstPixel  = ARGB8888_ALPHA_MASK;
   519                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.red / OWF_RED_MAX_VALUE))   <<
   569                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.red / OWF_RED_MAX_VALUE))   <<
   520                                 ARGB8888_RED_SHIFT);
   570                                 ARGB8888_RED_SHIFT);
   521                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.green / OWF_GREEN_MAX_VALUE)) <<
   571                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.green / OWF_GREEN_MAX_VALUE)) <<
   522                                 ARGB8888_GREEN_SHIFT);
   572                                 ARGB8888_GREEN_SHIFT);
   523                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.blue / OWF_BLUE_MAX_VALUE))  <<
   573                     dstPixel |= ((OWFuint8)(roundSubPixel(OWF_BYTE_MAX_VALUE * srcPtr->color.blue / OWF_BLUE_MAX_VALUE))  <<
   524                                 ARGB8888_BLUE_SHIFT);
   574                                 ARGB8888_BLUE_SHIFT);
       
   575 #else
       
   576                     dstPixel = *(OWFuint32*)srcPtr | ARGB8888_ALPHA_MASK;
       
   577 #endif
   525                     *dstPtr = dstPixel;
   578                     *dstPtr = dstPixel;
   526                     dstPtr ++;
   579                     dstPtr ++;
   527                     srcPtr ++;
   580                     srcPtr ++;
   528                 }
   581                 }
   529                 break;
   582                 break;
   541 
   594 
   542 /*----------------------------------------------------------------------------*/
   595 /*----------------------------------------------------------------------------*/
   543 OWF_API_CALL void
   596 OWF_API_CALL void
   544 OWF_Image_Init(OWF_IMAGE* image)
   597 OWF_Image_Init(OWF_IMAGE* image)
   545 {
   598 {
       
   599     DPRINT(("OWF_Image_Init"));
       
   600 
   546     OWF_ASSERT(NULL != image);
   601     OWF_ASSERT(NULL != image);
   547     memset(image, 0, sizeof(OWF_IMAGE));
   602     memset(image, 0, sizeof(OWF_IMAGE));
   548 }
   603 }
   549 
   604 
   550 /*----------------------------------------------------------------------------*/
   605 /*----------------------------------------------------------------------------*/
   555                  void* buffer,
   610                  void* buffer,
   556                  OWFint minimumStride
   611                  OWFint minimumStride
   557                  )
   612                  )
   558 {
   613 {
   559     OWF_IMAGE*      image;
   614     OWF_IMAGE*      image;
       
   615 
       
   616     DPRINT(("OWF_Image_Create"));
   560 
   617 
   561     image = CREATE(OWF_IMAGE);
   618     image = CREATE(OWF_IMAGE);
   562 
   619 
   563     if (image)
   620     if (image)
   564     {
   621     {
   632 OWF_API_CALL OWF_IMAGE*
   689 OWF_API_CALL OWF_IMAGE*
   633 OWF_Image_Copy(const OWF_IMAGE* image)
   690 OWF_Image_Copy(const OWF_IMAGE* image)
   634 {
   691 {
   635     OWF_IMAGE* newImage = NULL;
   692     OWF_IMAGE* newImage = NULL;
   636 
   693 
       
   694     DPRINT(("OWF_Image_Copy"));
       
   695 
   637     OWF_ASSERT(image);
   696     OWF_ASSERT(image);
   638 
   697 
   639     newImage = CREATE(OWF_IMAGE);
   698     newImage = CREATE(OWF_IMAGE);
   640     if (newImage)
   699     if (newImage)
   641     {
   700     {
   662                   OWFint height)
   721                   OWFint height)
   663 {
   722 {
   664     OWFint                  size;
   723     OWFint                  size;
   665     OWFint                  stride;
   724     OWFint                  stride;
   666 
   725 
       
   726     DPRINT(("OWF_Image_SetSize"));
       
   727 
   667     OWF_ASSERT(image);
   728     OWF_ASSERT(image);
   668     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL ||
   729     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL ||
   669             image->format.pixelFormat==OWF_IMAGE_L32);
   730             image->format.pixelFormat==OWF_IMAGE_L32);
   670     
   731     
   671     /** note that this setsize ignores any specialised stride **/
   732     /** note that this setsize ignores any specialised stride **/
   686 OWF_API_CALL void
   747 OWF_API_CALL void
   687 OWF_Image_SetFlags(OWF_IMAGE* image,
   748 OWF_Image_SetFlags(OWF_IMAGE* image,
   688                   OWFboolean premultiply,
   749                   OWFboolean premultiply,
   689                   OWFboolean linear)
   750                   OWFboolean linear)
   690     {
   751     {
       
   752     DPRINT(("OWF_Image_SetFlags"));
       
   753 
   691     OWF_ASSERT(image);
   754     OWF_ASSERT(image);
   692     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL ||
   755     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL ||
   693             image->format.pixelFormat==OWF_IMAGE_L32);
   756             image->format.pixelFormat==OWF_IMAGE_L32);
   694     image->format.linear=linear;
   757     image->format.linear=linear;
   695     image->format.premultiplied=premultiply;
   758     image->format.premultiplied=premultiply;
   697 
   760 
   698 /*----------------------------------------------------------------------------*/
   761 /*----------------------------------------------------------------------------*/
   699 OWF_API_CALL void
   762 OWF_API_CALL void
   700 OWF_Image_SetPixelBuffer(OWF_IMAGE* image,      void* buffer)
   763 OWF_Image_SetPixelBuffer(OWF_IMAGE* image,      void* buffer)
   701     {
   764     {
       
   765     DPRINT(("OWF_Image_SetPixelBuffer"));
       
   766 
   702     OWF_ASSERT(image);
   767     OWF_ASSERT(image);
   703     OWF_ASSERT(buffer);
   768     OWF_ASSERT(buffer);
   704     OWF_ASSERT(image->foreign);
   769     OWF_ASSERT(image->foreign);
   705     if (image->foreign)
   770     if (image->foreign)
   706         {
   771         {
   761     OWFint                  lineCount   = 0;
   826     OWFint                  lineCount   = 0;
   762     OWFint                  copyStride  = 0;
   827     OWFint                  copyStride  = 0;
   763     OWFuint8*               srcPtr      = NULL;
   828     OWFuint8*               srcPtr      = NULL;
   764     OWFuint8*               dstPtr      = NULL;
   829     OWFuint8*               dstPtr      = NULL;
   765 
   830 
       
   831     DPRINT(("OWF_Image_Blit"));
       
   832 
   766     OWF_ASSERT(dst != 0 && dst->data != NULL);
   833     OWF_ASSERT(dst != 0 && dst->data != NULL);
   767     OWF_ASSERT(src != 0 && src->data != NULL);
   834     OWF_ASSERT(src != 0 && src->data != NULL);
   768     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   835     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   769     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   836     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
   770 
   837 
   898                                    OWF_RECTANGLE* dstRect,
   965                                    OWF_RECTANGLE* dstRect,
   899                                    OWF_IMAGE* src,
   966                                    OWF_IMAGE* src,
   900                                    OWFfloat* srcRect)
   967                                    OWFfloat* srcRect)
   901 {
   968 {
   902     OWFint                  ox = 0, oy = 0;
   969     OWFint                  ox = 0, oy = 0;
   903     OWFfloat                dx = 0.f, dy = 0.f; 
       
   904     OWFint                  x, y;
   970     OWFint                  x, y;
       
   971 
       
   972     DPRINT(("OWF_Image_PointSamplingStretchBlit"));
   905 
   973 
   906     /* images must be valid */
   974     /* images must be valid */
   907     if (!((src != NULL) && (src->data != NULL) &&
   975     if (!((src != NULL) && (src->data != NULL) &&
   908           (dst != NULL) && (dst->data != NULL)))
   976           (dst != NULL) && (dst->data != NULL)))
   909     {
   977     {
   924     if (src->pixelSize != dst->pixelSize)
   992     if (src->pixelSize != dst->pixelSize)
   925     {
   993     {
   926         return OWF_FALSE;
   994         return OWF_FALSE;
   927     }
   995     }
   928 
   996 
   929     /* solve scaling ratios for image */
   997 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
   930     dx = (OWFfloat) srcRect[2] / (OWFfloat) dstRect->width;
   998     {
   931     dy = (OWFfloat) srcRect[3] / (OWFfloat) dstRect->height;
   999         OWFfloat                dx = 0.f, dy = 0.f; 
   932 
  1000     
   933     for (y = 0; y < dstRect->height; y++)
  1001         /* solve scaling ratios for image */
   934     {
  1002         dx = (OWFfloat) srcRect[2] / (OWFfloat) dstRect->width;
   935         for (x = 0; x < dstRect->width; x++) 
  1003         dy = (OWFfloat) srcRect[3] / (OWFfloat) dstRect->height;
   936         {
  1004     
   937             OWFpixel*       pixel;         
  1005         for (y = 0; y < dstRect->height; y++)
   938             
  1006         {
   939             /* NOTE This code uses pixel center points to calculate distances
  1007             for (x = 0; x < dstRect->width; x++) 
   940                     and factors. Results can differ slightly when pixel corner
  1008             {
   941                     coordinates are used */            
  1009                 OWFpixel*       pixel;         
   942             
  1010                 
   943             /* coordinates of nearest pixel in original image */
  1011                 /* NOTE This code uses pixel center points to calculate distances
   944             ox = (int) floor((((OWFfloat) x + 0.5) * dx) + srcRect[0]);
  1012                         and factors. Results can differ slightly when pixel corner
   945             oy = (int) floor((((OWFfloat) y + 0.5) * dy) + srcRect[1]);     
  1013                         coordinates are used */            
   946             
  1014                 
   947             pixel = OWF_Image_GetPixelPtr(src,
  1015                 /* coordinates of nearest pixel in original image */
   948                                           ox,
  1016                 ox = (int) floor((((OWFfloat) x + 0.5) * dx) + srcRect[0]);
   949                                           oy);
  1017                 oy = (int) floor((((OWFfloat) y + 0.5) * dy) + srcRect[1]);     
   950             
  1018                 
   951             OWF_Image_SetPixel(dst,
  1019                 pixel = OWF_Image_GetPixelPtr(src,
   952                                dstRect->x + x,
  1020                                               ox,
   953                                dstRect->y + y,
  1021                                               oy);
   954                                pixel);
  1022                 
   955             
  1023                 OWF_Image_SetPixel(dst,
   956         }
  1024                                    dstRect->x + x,
   957     }
  1025                                    dstRect->y + y,
       
  1026                                    pixel);
       
  1027                 
       
  1028             }
       
  1029         }
       
  1030     }
       
  1031 #else
       
  1032     if (srcRect[0] < 0 || (srcRect[0] + srcRect[2]) > src->width ||
       
  1033             srcRect[1] < 0 || (srcRect[1] + srcRect[3]) > src->height)
       
  1034         {
       
  1035         /* Source rectangle out of bounds */
       
  1036         return OWF_FALSE;
       
  1037         }
       
  1038 
       
  1039     if (dstRect->x < 0 || (dstRect->x + dstRect->width) > dst->width ||
       
  1040             dstRect->y < 0 || (dstRect->y + dstRect->height) > dst->height)
       
  1041         {
       
  1042         /* Destination rectangle out of bounds */
       
  1043         return OWF_FALSE;
       
  1044         }
       
  1045 
       
  1046     {
       
  1047         OWFint dxFix, dyFix;
       
  1048         OWFint xFixStart, yFix;
       
  1049         OWFuint32 *dstPtr, *srcLinePtr;
       
  1050     
       
  1051 /* Integer <-> 16.16 fixed point conversion macros */
       
  1052 #define INT_TO_FIXED_PT(X) ((X) << 16)
       
  1053 #define FIXED_PT_TO_INT(X) ((X) >> 16)
       
  1054     
       
  1055         /* Calculate scaling factors in fixed point (with rounding). */
       
  1056         dxFix = (OWFint)((srcRect[2] * INT_TO_FIXED_PT(1) + (dstRect->width >> 1)) / dstRect->width);
       
  1057         dyFix = (OWFint)((srcRect[3] * INT_TO_FIXED_PT(1) + (dstRect->height >> 1)) / dstRect->height);
       
  1058     
       
  1059         /* Calculate fixed point location in source, with half-pixel offset */
       
  1060         xFixStart = (OWFint)(srcRect[0] * INT_TO_FIXED_PT(1) + (dxFix >> 1));
       
  1061         yFix = (OWFint)(srcRect[1] * INT_TO_FIXED_PT(1) + (dyFix >> 1));
       
  1062     
       
  1063         /* Initial target address. */
       
  1064         dstPtr = (OWFuint32*)dst->data + dstRect->y * dst->width + dstRect->x;
       
  1065     
       
  1066         for (y = 0; y < dstRect->height; y++)
       
  1067         {
       
  1068             OWFint xFix = xFixStart;
       
  1069     
       
  1070             oy = FIXED_PT_TO_INT(yFix);
       
  1071             srcLinePtr = (OWFuint32*)src->data + oy * src->width;
       
  1072     
       
  1073             for (x = 0; x < dstRect->width; x++) 
       
  1074             {
       
  1075                 ox = FIXED_PT_TO_INT(xFix);
       
  1076                 dstPtr[x] = srcLinePtr[ox];
       
  1077                 xFix += dxFix;
       
  1078             }
       
  1079     
       
  1080             dstPtr += dst->width;
       
  1081             yFix += dyFix;
       
  1082         }
       
  1083     }
       
  1084 #endif
   958     return OWF_TRUE;
  1085     return OWF_TRUE;
   959 }
  1086 }
   960 
  1087 
   961 /*----------------------------------------------------------------------------*/
  1088 /*----------------------------------------------------------------------------*/
   962 OWF_API_CALL OWFboolean
  1089 OWF_API_CALL OWFboolean
   970     OWFfloat                dx = 0.f, dy = 0.f, wx = 0.f, wy = 0.f;
  1097     OWFfloat                dx = 0.f, dy = 0.f, wx = 0.f, wy = 0.f;
   971     OWFfloat                w[2 * 2];
  1098     OWFfloat                w[2 * 2];
   972     OWFpixel*               sample[4];
  1099     OWFpixel*               sample[4];
   973     OWFpixel*               pixel = NULL;
  1100     OWFpixel*               pixel = NULL;
   974 
  1101 
       
  1102     DPRINT(("OWF_Image_BilinearStretchBlit"));
       
  1103 
   975     /* images must be valid */
  1104     /* images must be valid */
   976     if (!((src != NULL) && (src->data != NULL) &&
  1105     if (!((src != NULL) && (src->data != NULL) &&
   977           (dst != NULL) && (dst->data != NULL)))
  1106           (dst != NULL) && (dst->data != NULL)))
   978     {
  1107     {
   979         return OWF_FALSE;
  1108         return OWF_FALSE;
  1115                 OWFsubpixel alpha)
  1244                 OWFsubpixel alpha)
  1116 {
  1245 {
  1117     OWFint                  i, numPixels;
  1246     OWFint                  i, numPixels;
  1118     OWFpixel*                pixels;
  1247     OWFpixel*                pixels;
  1119 
  1248 
       
  1249     DPRINT(("OWF_Image_Clear"));
       
  1250 
  1120     OWF_ASSERT(image != 0);
  1251     OWF_ASSERT(image != 0);
  1121     OWF_ASSERT(image->data != 0);
  1252     OWF_ASSERT(image->data != 0);
  1122     OWF_ASSERT(image->format.pixelFormat == OWF_IMAGE_ARGB_INTERNAL);
  1253     OWF_ASSERT(image->format.pixelFormat == OWF_IMAGE_ARGB_INTERNAL);
       
  1254     /* Note: image->stride cannot be relied upon to be correct. Assume lines are contiguous. */
  1123 
  1255 
  1124     numPixels = image->width * image->height;
  1256     numPixels = image->width * image->height;
  1125     pixels = (OWFpixel*) image->data;
  1257     pixels = (OWFpixel*) image->data;
  1126 
  1258 
       
  1259 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
  1127     for (i = 0; i < numPixels; i++)
  1260     for (i = 0; i < numPixels; i++)
  1128     {
  1261     {
  1129         pixels[i].color.red   = (OWFsubpixel) red;
  1262         pixels[i].color.red   = (OWFsubpixel) red;
  1130         pixels[i].color.green = (OWFsubpixel) green;
  1263         pixels[i].color.green = (OWFsubpixel) green;
  1131         pixels[i].color.blue  = (OWFsubpixel) blue;
  1264         pixels[i].color.blue  = (OWFsubpixel) blue;
  1132         pixels[i].color.alpha = (OWFsubpixel) alpha;
  1265         pixels[i].color.alpha = (OWFsubpixel) alpha;
  1133     }
  1266     }
       
  1267 #else
       
  1268     if (alpha == red && alpha == green && alpha == blue)
       
  1269         {
       
  1270         /* If all four bytes are the same, just use memset */
       
  1271         OWFuint32 clearBytes = numPixels * sizeof(OWFuint32);
       
  1272 
       
  1273         memset(pixels, alpha, clearBytes);
       
  1274         }
       
  1275     else
       
  1276         {
       
  1277         /* Otherwise assign each pixel the packed value */
       
  1278         OWFuint32* pixelPtr = (OWFuint32*)pixels;
       
  1279         OWFuint32 pixel;
       
  1280     
       
  1281         pixel = (alpha << ARGB8888_ALPHA_SHIFT) | (red << ARGB8888_RED_SHIFT) |
       
  1282                 (green << ARGB8888_GREEN_SHIFT) | (blue << ARGB8888_BLUE_SHIFT);
       
  1283 
       
  1284         for (i = 0; i < numPixels; i++)
       
  1285             {
       
  1286             pixelPtr[i] = pixel;
       
  1287             }
       
  1288         }
       
  1289 #endif
  1134 }
  1290 }
  1135 
  1291 
  1136 /*----------------------------------------------------------------------------*/
  1292 /*----------------------------------------------------------------------------*/
  1137 OWF_API_CALL void
  1293 OWF_API_CALL void
  1138 OWF_Image_PremultiplyAlpha(OWF_IMAGE* image)
  1294 OWF_Image_PremultiplyAlpha(OWF_IMAGE* image)
  1139 {
  1295 {
  1140     OWFint       x, y;
  1296     OWFint       x, y;
       
  1297 
       
  1298     DPRINT(("OWF_Image_PremultiplyAlpha"));
  1141 
  1299 
  1142     OWF_ASSERT(image != 0);
  1300     OWF_ASSERT(image != 0);
  1143 
  1301 
  1144     if (image->format.premultiplied)
  1302     if (image->format.premultiplied)
  1145     {
  1303     {
  1189 OWF_Image_UnpremultiplyAlpha(OWF_IMAGE* image)
  1347 OWF_Image_UnpremultiplyAlpha(OWF_IMAGE* image)
  1190 {
  1348 {
  1191     OWFint       count;
  1349     OWFint       count;
  1192     OWFpixel*    pixelPtr;
  1350     OWFpixel*    pixelPtr;
  1193 
  1351 
       
  1352     DPRINT(("OWF_Image_UnpremultiplyAlpha"));
       
  1353 
  1194     OWF_ASSERT(image != 0);
  1354     OWF_ASSERT(image != 0);
  1195 
  1355 
  1196     if (!image->format.premultiplied)
  1356     if (!image->format.premultiplied)
  1197     {
  1357     {
  1198         return;
  1358         return;
  1243     OWFint                  ox = 0, oy = 0,
  1403     OWFint                  ox = 0, oy = 0,
  1244                             w = 0, h = 0,
  1404                             w = 0, h = 0,
  1245                             x = 0, y = 0;
  1405                             x = 0, y = 0;
  1246     OWFint                  xx = 0, xy = 0,
  1406     OWFint                  xx = 0, xy = 0,
  1247                             yx = 0, yy = 0;
  1407                             yx = 0, yy = 0;
       
  1408 
       
  1409     DPRINT(("OWF_Image_Rotate"));
  1248 
  1410 
  1249     OWF_ASSERT(src && src->data);
  1411     OWF_ASSERT(src && src->data);
  1250     OWF_ASSERT(dst && dst->data);
  1412     OWF_ASSERT(dst && dst->data);
  1251     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1413     OWF_ASSERT(src->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1252     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1414     OWF_ASSERT(dst->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1341 OWF_Image_Flip(OWF_IMAGE* image,
  1503 OWF_Image_Flip(OWF_IMAGE* image,
  1342                OWF_FLIP_DIRECTION dir)
  1504                OWF_FLIP_DIRECTION dir)
  1343 {
  1505 {
  1344     OWFint                  x, y;
  1506     OWFint                  x, y;
  1345 
  1507 
       
  1508     DPRINT(("OWF_Image_Flip"));
       
  1509 
  1346     if (!image)
  1510     if (!image)
  1347     {
  1511     {
  1348         return;
  1512         return;
  1349     }
  1513     }
  1350     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1514     OWF_ASSERT(image->format.pixelFormat==OWF_IMAGE_ARGB_INTERNAL);
  1395 /*----------------------------------------------------------------------------*/
  1559 /*----------------------------------------------------------------------------*/
  1396 #define BLENDER_INNER_LOOP_BEGIN \
  1560 #define BLENDER_INNER_LOOP_BEGIN \
  1397     OWFint rowCount = drect.height; \
  1561     OWFint rowCount = drect.height; \
  1398     while (rowCount > 0) { \
  1562     while (rowCount > 0) { \
  1399         OWFint colCount = drect.width; \
  1563         OWFint colCount = drect.width; \
  1400         while (colCount > 0) { \
  1564         while (colCount > 0) {
  1401             if (!(blend->tsColor && COLOR_MATCH(SC, TSC))) \
       
  1402             { \
       
  1403 
  1565 
  1404 #define BLENDER_INNER_LOOP_END \
  1566 #define BLENDER_INNER_LOOP_END \
  1405                 DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \
       
  1406             } /* end tsColor check */ \
       
  1407             srcPtr ++; \
  1567             srcPtr ++; \
  1408             dstPtr ++; \
  1568             dstPtr ++; \
  1409             maskPtr++; \
  1569             maskPtr++; \
  1410             --colCount; \
  1570             --colCount; \
  1411         } \
  1571         } \
  1414         maskPtr += maskLineDelta; \
  1574         maskPtr += maskLineDelta; \
  1415         --rowCount; \
  1575         --rowCount; \
  1416     }
  1576     }
  1417 	
  1577 	
  1418 #define BLENDER_INNER_LOOP_END_NO_MASK \
  1578 #define BLENDER_INNER_LOOP_END_NO_MASK \
  1419                 DA = blend->destinationFullyOpaque ? OWF_FULLY_OPAQUE : DA; \
       
  1420             } /* end tsColor check */ \
       
  1421             srcPtr ++; \
  1579             srcPtr ++; \
  1422             dstPtr ++; \
  1580             dstPtr ++; \
  1423             --colCount; \
  1581             --colCount; \
  1424         } \
  1582         } \
  1425         srcPtr += srcLineDelta; \
  1583         srcPtr += srcLineDelta; \
  1426         dstPtr += dstLineDelta; \
  1584         dstPtr += dstLineDelta; \
  1427         --rowCount; \
  1585         --rowCount; \
  1428     }
  1586     }
  1429 
       
  1430 #define TSC blend->tsColor->color
       
  1431 #define SC srcPtr->color
       
  1432 
       
  1433 /* Note: actually would be better to compare integer values
       
  1434  * for TSC match -> eliminate float arithmetic pitfalls
       
  1435  */
       
  1436 #define COLOR_MATCH(x, y) (x.red==y.red && x.green==y.green && x.blue==y.blue)
       
  1437 
  1587 
  1438 #define SA srcPtr->color.alpha
  1588 #define SA srcPtr->color.alpha
  1439 #define SR srcPtr->color.red
  1589 #define SR srcPtr->color.red
  1440 #define SG srcPtr->color.green
  1590 #define SG srcPtr->color.green
  1441 #define SB srcPtr->color.blue
  1591 #define SB srcPtr->color.blue
  1558             /*
  1708             /*
  1559             rgb     = src.rgb
  1709             rgb     = src.rgb
  1560             alpha    = 1
  1710             alpha    = 1
  1561             */
  1711             */
  1562             BLENDER_INNER_LOOP_BEGIN;
  1712             BLENDER_INNER_LOOP_BEGIN;
       
  1713 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
  1563                 DR = SR;
  1714                 DR = SR;
  1564                 DG = SG;
  1715                 DG = SG;
  1565                 DB = SB;
  1716                 DB = SB;
  1566                 DA = OWF_FULLY_OPAQUE;
  1717                 DA = OWF_FULLY_OPAQUE;
       
  1718 #else
       
  1719                 *(OWFuint32*)dstPtr = *(OWFuint32*)srcPtr | ARGB8888_ALPHA_MASK;
       
  1720 #endif
  1567             BLENDER_INNER_LOOP_END_NO_MASK;
  1721             BLENDER_INNER_LOOP_END_NO_MASK;
  1568             break;
  1722             break;
  1569         }
  1723         }
  1570 
  1724 
  1571         case OWF_TRANSPARENCY_GLOBAL_ALPHA:
  1725         case OWF_TRANSPARENCY_GLOBAL_ALPHA:
  1587             break;
  1741             break;
  1588         }
  1742         }
  1589 
  1743 
  1590         case OWF_TRANSPARENCY_SOURCE_ALPHA:
  1744         case OWF_TRANSPARENCY_SOURCE_ALPHA:
  1591         {
  1745         {
       
  1746 #ifndef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
       
  1747         OWFuint32 redBlueMask = (ARGB8888_RED_MASK | ARGB8888_BLUE_MASK);
       
  1748         OWFuint32 alphaGreenMask = (ARGB8888_ALPHA_MASK | ARGB8888_GREEN_MASK);
       
  1749         OWFuint32 halfRedBlue = 0x00800080;
       
  1750 #endif
  1592             /*
  1751             /*
  1593             rgb     = src.rgb + dst.rgb * (1 - src.alpha)
  1752             rgb     = src.rgb + dst.rgb * (1 - src.alpha)
  1594             alpha    = src.alpha + dst.alpha * (1 - src.alpha)
  1753             alpha    = src.alpha + dst.alpha * (1 - src.alpha)
  1595             */
  1754             */
  1596             BLENDER_INNER_LOOP_BEGIN;
  1755             BLENDER_INNER_LOOP_BEGIN;
  1597                 DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1756 #ifdef OWF_IMAGE_INTERNAL_PIXEL_IS_FLOAT
  1598                 DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1757             DR = SR + (DR * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1599                 DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1758             DG = SG + (DG * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1600                 DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
  1759             DB = SB + (DB * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1760             DA = SA + (DA * (OWF_FULLY_OPAQUE - SA) + OWF_BLEND_ROUNDING_VALUE) / OWF_ALPHA_MAX_VALUE;
       
  1761 #else
       
  1762             {
       
  1763                 OWFuint32 srcP = *(OWFuint32*)srcPtr;
       
  1764                 OWFuint8 srcA = srcP >> ARGB8888_ALPHA_SHIFT;
       
  1765 
       
  1766                 if (srcA == OWF_ALPHA_MAX_VALUE)
       
  1767                     {
       
  1768                     /* Fully opaque source pixel */
       
  1769                     *(OWFuint32*)dstPtr = srcP;
       
  1770                     }
       
  1771                 else
       
  1772                     {
       
  1773                     if (srcA)
       
  1774                         {
       
  1775                         /* Not fully transparent source pixel. Algorithm after Jim Blinn */
       
  1776                         OWFuint32 mask = 0xFF - srcA;
       
  1777                         OWFuint32 dstP = *(OWFuint32*)dstPtr;
       
  1778                         OWFuint32 blend;
       
  1779 
       
  1780                         blend = mask * (dstP & redBlueMask) + halfRedBlue;
       
  1781                         srcP += ((blend + ((blend >> 8) & redBlueMask) >> 8)) & redBlueMask;
       
  1782                         blend = mask * ((dstP >> 8) & redBlueMask) + halfRedBlue;
       
  1783                         srcP += (blend + ((blend >> 8) & redBlueMask)) & alphaGreenMask;
       
  1784 
       
  1785                         *(OWFuint32*)dstPtr = srcP;
       
  1786                         }
       
  1787                     }
       
  1788             }
       
  1789 #endif
  1601             BLENDER_INNER_LOOP_END_NO_MASK;
  1790             BLENDER_INNER_LOOP_END_NO_MASK;
  1602             break;
  1791             break;
  1603         }
  1792         }
  1604 
  1793 
  1605         case OWF_TRANSPARENCY_MASK:
  1794         case OWF_TRANSPARENCY_MASK:
  1681 OWF_Image_AllocData(OWF_DISPCTX dc, OWFint width, OWFint height, OWF_PIXEL_FORMAT pixelFormat)
  1870 OWF_Image_AllocData(OWF_DISPCTX dc, OWFint width, OWFint height, OWF_PIXEL_FORMAT pixelFormat)
  1682 {
  1871 {
  1683     OWF_IMAGE_FORMAT        imgf;
  1872     OWF_IMAGE_FORMAT        imgf;
  1684     OWFint                  stride;
  1873     OWFint                  stride;
  1685 
  1874 
       
  1875     DPRINT(("OWF_Image_AllocData"));
       
  1876 
  1686     /* kludge. GetStride need pixelFormat. */
  1877     /* kludge. GetStride need pixelFormat. */
  1687     imgf.pixelFormat = pixelFormat;
  1878     imgf.pixelFormat = pixelFormat;
  1688     imgf.rowPadding = OWF_Image_GetFormatPadding(pixelFormat);
  1879     imgf.rowPadding = OWF_Image_GetFormatPadding(pixelFormat);
  1689     stride = OWF_Image_GetStride(width, &imgf, 0);
  1880     stride = OWF_Image_GetStride(width, &imgf, 0);
  1690 
  1881 
  1705 
  1896 
  1706 /*----------------------------------------------------------------------------*/
  1897 /*----------------------------------------------------------------------------*/
  1707 OWF_API_CALL void
  1898 OWF_API_CALL void
  1708 OWF_Image_FreeData(OWF_DISPCTX dc, void** data)
  1899 OWF_Image_FreeData(OWF_DISPCTX dc, void** data)
  1709 {
  1900 {
       
  1901     DPRINT(("OWF_Image_FreeData"));
       
  1902 
  1710     if (*data)
  1903     if (*data)
  1711     {
  1904     {
  1712     if (dc)
  1905     if (dc)
  1713         {
  1906         {
  1714         OWF_DisplayContext_ScratchBuffer_Destroy(dc, *data);
  1907         OWF_DisplayContext_ScratchBuffer_Destroy(dc, *data);
  1723 
  1916 
  1724 /*----------------------------------------------------------------------------*/
  1917 /*----------------------------------------------------------------------------*/
  1725 OWF_API_CALL OWFint
  1918 OWF_API_CALL OWFint
  1726 OWF_Image_GetFormatPixelSize(OWF_PIXEL_FORMAT format)
  1919 OWF_Image_GetFormatPixelSize(OWF_PIXEL_FORMAT format)
  1727 {
  1920 {
       
  1921     DPRINT(("OWF_Image_GetFormatPixelSize"));
       
  1922 
  1728     switch (format)
  1923     switch (format)
  1729     {
  1924     {
  1730         case OWF_IMAGE_ARGB_INTERNAL:
  1925         case OWF_IMAGE_ARGB_INTERNAL:
  1731         {
  1926         {
  1732             return sizeof(OWFpixel);
  1927             return sizeof(OWFpixel);
  1772 /*----------------------------------------------------------------------------*/
  1967 /*----------------------------------------------------------------------------*/
  1773 OWF_API_CALL OWFint
  1968 OWF_API_CALL OWFint
  1774 OWF_Image_GetFormatPadding(OWF_PIXEL_FORMAT format)
  1969 OWF_Image_GetFormatPadding(OWF_PIXEL_FORMAT format)
  1775 {
  1970 {
  1776     OWFint                  padding = 1;
  1971     OWFint                  padding = 1;
       
  1972 
       
  1973     DPRINT(("OWF_Image_GetFormatPadding"));
  1777 
  1974 
  1778     switch (format)
  1975     switch (format)
  1779     {
  1976     {
  1780         case OWF_IMAGE_ARGB_INTERNAL:
  1977         case OWF_IMAGE_ARGB_INTERNAL:
  1781         {
  1978         {
  1832 
  2029 
  1833 /*----------------------------------------------------------------------------*/
  2030 /*----------------------------------------------------------------------------*/
  1834 OWF_API_CALL void
  2031 OWF_API_CALL void
  1835 OWF_Image_SwapWidthAndHeight(OWF_IMAGE* image)
  2032 OWF_Image_SwapWidthAndHeight(OWF_IMAGE* image)
  1836 {
  2033 {
       
  2034     DPRINT(("OWF_Image_SwapWidthAndHeight"));
       
  2035 
  1837     /* swap w & h. Note that original stride is not restored if swap back. */
  2036     /* swap w & h. Note that original stride is not restored if swap back. */
  1838     image->width ^= image->height;
  2037     image->width ^= image->height;
  1839     image->height ^= image->width;
  2038     image->height ^= image->width;
  1840     image->width ^= image->height;
  2039     image->width ^= image->height;
  1841 
  2040