Now that Owen explained the algorithm, I think I implemented it right for
* gdk-pixbuf/pixops/pixops.c: (pixops_composite_nearest), (composite_pixel), (composite_line): * gdk-pixbuf/test-gdk-pixbuf.c: (simple_composite_test_one_type): Now that Owen explained the algorithm, I think I implemented it right for the cases where the destination pixbuf is not opaque. The test does seem to confirm it.
This commit is contained in:
		@ -1,3 +1,12 @@
 | 
			
		||||
2000-05-04  Darin Adler  <darin@eazel.com>
 | 
			
		||||
 | 
			
		||||
	* gdk-pixbuf/pixops/pixops.c: (pixops_composite_nearest),
 | 
			
		||||
	(composite_pixel), (composite_line):
 | 
			
		||||
	* gdk-pixbuf/test-gdk-pixbuf.c: (simple_composite_test_one_type):
 | 
			
		||||
	Now that Owen explained the algorithm, I think I implemented it
 | 
			
		||||
	right for the cases where the destination pixbuf is not opaque.
 | 
			
		||||
	The test does seem to confirm it.
 | 
			
		||||
 | 
			
		||||
2000-05-04  Darin Adler  <darin@eazel.com>
 | 
			
		||||
 | 
			
		||||
	* gdk-pixbuf/.cvsignore:
 | 
			
		||||
 | 
			
		||||
@ -177,10 +177,24 @@ pixops_composite_nearest (guchar        *dest_buf,
 | 
			
		||||
 | 
			
		||||
	  if (dest_has_alpha)
 | 
			
		||||
	    {
 | 
			
		||||
	      dest[0] = (a0 * src[0] + (0xff - a0) * dest[0]) / 0xff;
 | 
			
		||||
	      dest[1] = (a0 * src[1] + (0xff - a0) * dest[1]) / 0xff;
 | 
			
		||||
	      dest[2] = (a0 * src[2] + (0xff - a0) * dest[2]) / 0xff;
 | 
			
		||||
	      dest[3] = (0xff * a0 + (0xff - a0) * dest[3]) / 0xff;
 | 
			
		||||
	      unsigned int w0 = 0xff * a0;
 | 
			
		||||
	      unsigned int w1 = (0xff - a0) * dest[3];
 | 
			
		||||
	      unsigned int w = w0 + w1;
 | 
			
		||||
 | 
			
		||||
	      if (w != 0)
 | 
			
		||||
		{
 | 
			
		||||
		  dest[0] = (w0 * src[0] + w1 * dest[0]) / w;
 | 
			
		||||
		  dest[1] = (w0 * src[1] + w1 * dest[1]) / w;
 | 
			
		||||
		  dest[2] = (w0 * src[2] + w1 * dest[2]) / w;
 | 
			
		||||
		  dest[3] = w / 0xff;
 | 
			
		||||
		}
 | 
			
		||||
	      else
 | 
			
		||||
		{
 | 
			
		||||
		  dest[0] = 0;
 | 
			
		||||
		  dest[1] = 0;
 | 
			
		||||
		  dest[2] = 0;
 | 
			
		||||
		  dest[3] = 0;
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
@ -296,12 +310,24 @@ composite_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha
 | 
			
		||||
{
 | 
			
		||||
  if (dest_has_alpha)
 | 
			
		||||
    {
 | 
			
		||||
      unsigned int w = (0xff0000 - a) * dest[3];
 | 
			
		||||
      unsigned int w0 = a - (a >> 8);
 | 
			
		||||
      unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3];
 | 
			
		||||
      unsigned int w = w0 + w1;
 | 
			
		||||
      
 | 
			
		||||
      dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000;
 | 
			
		||||
      dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000;
 | 
			
		||||
      dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000;
 | 
			
		||||
      dest[3] = (0xff * a + (0xff0000 - a) * dest[3]) / 0xff0000;
 | 
			
		||||
      if (w != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  dest[0] = (r - (r >> 8) + w1 * dest[0]) / w;
 | 
			
		||||
	  dest[1] = (g - (g >> 8) + w1 * dest[1]) / w;
 | 
			
		||||
	  dest[2] = (b - (b >> 8) + w1 * dest[2]) / w;
 | 
			
		||||
	  dest[3] = w / 0xff00;
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  dest[0] = 0;
 | 
			
		||||
	  dest[1] = 0;
 | 
			
		||||
	  dest[2] = 0;
 | 
			
		||||
	  dest[3] = 0;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
@ -354,12 +380,24 @@ composite_line (int *weights, int n_x, int n_y,
 | 
			
		||||
 | 
			
		||||
      if (dest_has_alpha)
 | 
			
		||||
	{
 | 
			
		||||
	  unsigned int w = (0xff0000 - a) * dest[3];
 | 
			
		||||
	  unsigned int w0 = a - (a >> 8);
 | 
			
		||||
	  unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3];
 | 
			
		||||
	  unsigned int w = w0 + w1;
 | 
			
		||||
 | 
			
		||||
	  dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000;
 | 
			
		||||
	  dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000;
 | 
			
		||||
	  dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000;
 | 
			
		||||
	  dest[3] = (0xff * a + (0xff0000 - a) * dest[3]) / 0xff0000;
 | 
			
		||||
	  if (w != 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      dest[0] = (r - (r >> 8) + w1 * dest[0]) / w;
 | 
			
		||||
	      dest[1] = (g - (g >> 8) + w1 * dest[1]) / w;
 | 
			
		||||
	      dest[2] = (b - (b >> 8) + w1 * dest[2]) / w;
 | 
			
		||||
	      dest[3] = w / 0xff00;
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      dest[0] = 0;
 | 
			
		||||
	      dest[1] = 0;
 | 
			
		||||
	      dest[2] = 0;
 | 
			
		||||
	      dest[3] = 0;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -201,7 +201,8 @@ simple_composite_test_one_type (GdkInterpType type)
 | 
			
		||||
	success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000FF, TRUE, 0xFF0000FF);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00FF, TRUE, 0x00FF00FF);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FFFF, TRUE, 0x0000FFFF);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x7FFF7F80);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x00FF0080);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0xFF000080, TRUE, 0x00FF0040, TRUE, 0xCC32009F);
 | 
			
		||||
	success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
 | 
			
		||||
 | 
			
		||||
	return success;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user