]> source.dussan.org Git - tigervnc.git/commitdiff
Added implementation of the remote desktop scaling on basis of integer
authorgeorge82 <george82@3789f03b-4d11-0410-bbf8-ca57d06f2519>
Sun, 28 Oct 2007 10:32:01 +0000 (10:32 +0000)
committergeorge82 <george82@3789f03b-4d11-0410-bbf8-ca57d06f2519>
Sun, 28 Oct 2007 10:32:01 +0000 (10:32 +0000)
computing. It allow to double the scaling performance.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2363 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/ScaleFilters.cxx
common/rfb/ScaleFilters.h
common/rfb/ScaledPixelBuffer.cxx

index 2a3344cead99a8b7ccf3b18a1ae8997972b38a1a..50b9bd9057b91e5c16e758557d7656c130c06d60 100644 (file)
@@ -95,6 +95,8 @@ void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, SFilterWe
   double sxc;
   double offset = 0.5;
   double ratio = (double)dst_x / src_x;
+  double sum, nc;
+  int i, ci;
 
   SFilter sFilter = filters[filter_id];
   
@@ -110,11 +112,16 @@ void ScaleFilters::makeWeightTabs(int filter_id, int src_x, int dst_x, SFilterWe
     int i1 = int(__rfbmin(sxc+sFilter.radius+0.5, src_x));
 
     weightTabs[x].i0 = i0; weightTabs[x].i1 = i1;
-    weightTabs[x].weight = new double[i1-i0];
+    weightTabs[x].weight = new short[i1-i0];
+
+    // Calculate coeff to normalize the filter weights
+    for (sum = 0, i = i0; i < i1; i++) sum += sFilter.func(double(i)-sxc+0.5);
+    if (sum == 0.) nc = (double)(WEIGHT_OF_ONE); else nc = (double)(WEIGHT_OF_ONE)/sum;
+
 
     // Calculate the weight coeffs on the scale filter interval
-    for (int ci = 0, i = i0; i < i1; i++) {
-      weightTabs[x].weight[ci++] = (double)sFilter.func(double(i)-sxc+0.5);
+    for (ci = 0, i = i0; i < i1; i++) {
+      weightTabs[x].weight[ci++] = (short)floor((sFilter.func(double(i)-sxc+0.5) * nc) + 0.5);
     }
   }
 }
index b306f470224a45c76f11e157baafb77e0ba18d7d..0a8c482b6a969efebe8d9a1704f768a8df97346f 100644 (file)
 
 namespace rfb {
 
+  #define BITS_OF_CHANEL 8
+  #define BITS_OF_WEIGHT 14
+  #define FINALSHIFT 2 * BITS_OF_WEIGHT - BITS_OF_CHANEL
+  #define WEIGHT_OF_ONE 1 << BITS_OF_WEIGHT
+
   typedef double (*filter_func)(double x);
 
   const double pi = 3.14159265358979;
@@ -48,8 +53,8 @@ namespace rfb {
 
   // Scale filter weight table
   typedef struct {
-    short int i0, i1;  // Filter function interval, [i0..i1)
-    double *weight;    // Weight coefficients on the filter function interval
+    short i0, i1;  // Filter function interval, [i0..i1)
+    short *weight;    // Weight coefficients on the filter function interval
   } SFilterWeightTab;
 
 
index b7b3f3949869302572f50f1471367b910b85d010..a7714764f141ee39dfa63173195133117a6f2374 100644 (file)
@@ -125,8 +125,8 @@ inline U32 ScaledPixelBuffer::getSourcePixel(int x, int y) {
 void ScaledPixelBuffer::scaleRect(const Rect& rect) {
   Rect changed_rect;
   U8 *ptr, *ptrs, *px, *pxs;
-  double rx, gx, bx, red, green, blue, *xweight, *yweight, xWeight, yWeight;
-  int r, g, b, xwi, ywi;
+  int r, g, b, rx, gx, bx, red, green, blue, xwi, ywi;
+  short *xweight, *yweight, xWeight, yWeight;
 
   // Calculate the changed pixel rect in the scaled image
   changed_rect = calculateScaleBoundary(rect);
@@ -141,7 +141,8 @@ void ScaledPixelBuffer::scaleRect(const Rect& rect) {
     yweight = yWeightTabs[y].weight;
 
     for (int x = changed_rect.tl.x; x < changed_rect.br.x; x++) {
-      ywi = 0; red = 0; green = 0; blue = 0;
+      // Init the sum of colors with (1 << (shift-1)) for rounding
+      ywi = 0; red = green = blue = 1 << (FINALSHIFT-1);
       xweight = xWeightTabs[x].weight;
     
       // Calculate the scaled pixel value at (x, y) coordinates by
@@ -156,20 +157,20 @@ void ScaledPixelBuffer::scaleRect(const Rect& rect) {
         for (int xs = xWeightTabs[x].i0; xs < xWeightTabs[x].i1; xs++) {
           rgbFromPixel(*((U32*)px), r, g, b);
           xWeight = xweight[xwi++];
-          rx += r * xWeight;
-          gx += g * xWeight;
-          bx += b * xWeight;
+          rx += (int)xWeight * r;
+          gx += (int)xWeight * g;
+          bx += (int)xWeight * b;
           px += bytesPerSrcPixel;
         }
         yWeight = yweight[ywi++];
-        red += rx * yWeight;
-        green += gx * yWeight;
-        blue += bx * yWeight;
+        red +=   (int)yWeight * (rx >> BITS_OF_CHANEL);
+        green += (int)yWeight * (gx >> BITS_OF_CHANEL);
+        blue +=  (int)yWeight * (bx >> BITS_OF_CHANEL);
         pxs += bytesPerSrcRow;
       }
-      *ptr++ = U8(blue);
-      *ptr++ = U8(green);
-      *ptr++ = U8(red);
+      *ptr++ = U8(blue  >> FINALSHIFT);
+      *ptr++ = U8(green >> FINALSHIFT);
+      *ptr++ = U8(red   >> FINALSHIFT);
       ptr++;
     }
     ptrs += bytesPerScaledRow;