Diff of /cpyBuf.cpp [ed05d7] .. [895964] Maximize Restore

  Switch to side-by-side view

--- a/cpyBuf.cpp
+++ b/cpyBuf.cpp
@@ -16,7 +16,7 @@
 // Mass Ave, Cambridge, MA 02139, USA.
 
 /**
-* @file CypBuf.cpp
+* @file CpyBuf.cpp
 * This file is included in all four plug-ins (PTAdjust, PTCorrect, PTPerspect, and PTRemap)
 * It contains two functions for converting image buffers between photoshop and 
 * panotools internal formats.
@@ -32,51 +32,70 @@
 **/
 int cpyBufToPs(void *buf)
 {
+  // TODO: Actualy impliment tiling - loop through the Hort and Vert tiles retrieving a little data at a time.
+  //       for now use a tile the size of the filter rect.
+  // TODO: Use the crop feature of PanoTools to only process the data of the selection, use less memory.
+
   // some local variables for efficiency
-  int16 tileHeight = gFr->filterRect.bottom - gFr->filterRect.top;
-  int16 tileWidth = gFr->filterRect.right - gFr->filterRect.left;
-  Rect *outRect = &gFr->outRect;
-  Rect *filterRect = &gFr->filterRect;
-  int16 imageWidth = PHO.imageWidth;
-  int16 imageHeight = PHO.imageHeight;
-  int32 imageDepth = PHO.imageDepth;
-  int32 bytesPerPixel = (imageDepth/8) * 3;
+  int16 //tileHeight    = gFr->inTileHeight;// Prefered tile size.
+  //if(tileHeight == 0) 
+    tileHeight        = gFr->filterRect.bottom - gFr->filterRect.top;
+  int16 //tileWidth     = gFr->inTileWidth;
+  //if(tileWidth == 0)
+    tileWidth         = gFr->filterRect.right - gFr->filterRect.left;
+  Rect *outRect       = &gFr->outRect;
+  Rect *filterRect    = &gFr->filterRect;
+  int16 imageWidth    = gData->pho.imageWidth;
+  int16 imageHeight   = gData->pho.imageHeight;
+  int32 imageDepth    = gData->pho.imageDepth;
+  int32 bytesPerPixel = (imageDepth/8) * gData->pho.imagePlanes;
 
   // round up to the nearest horizontal and vertical tile count
-  uint16 tilesVert = (uint16)((tileHeight - 1 + imageHeight) / tileHeight);
+  uint16 tilesVert  = (uint16)((tileHeight - 1 + imageHeight) / tileHeight);
   uint16 tilesHoriz = (uint16)((tileWidth - 1 + imageWidth) / tileWidth);
 
   // Fixed numbers are 16.16 values 
   // the first 16 bits represent the whole number
   // the last 16 bits represent the fraction
   gFr->inputRate = (int32)1 << 16;
-  gFr->maskRate = (int32)1 << 16;
+  gFr->maskRate  = (int32)1 << 16;
  
   // loop through each tile makeing sure we don't go over the bounds
   // of the imageHeight or imageWidth
   for (uint16 vertTile = 0; vertTile < tilesVert; vertTile++)
   {
+    // layers can be bigger or smaller than whole image area but we want to copy only the area of whole image
+    outRect->top       = (int16)max(0, (vertTile * tileHeight - gFr->floatCoord.v));
+    outRect->bottom    = (int16)min(tileHeight, imageHeight - gFr->floatCoord.v);
+    uint16  OffSetV    = (uint16)max(0, gFr->floatCoord.v);
+    uint16  rectHeight = (uint16)(outRect->bottom - outRect->top);
+
     for (uint16 horizTile = 0; horizTile < tilesHoriz; horizTile++)
     {
-      outRect->top = (int16)(vertTile * tileHeight);
-      outRect->left = (int16)(horizTile * tileWidth);
-      outRect->bottom = (int16)(outRect->top + tileHeight);
-      outRect->right = (int16)(outRect->left + tileWidth);
-
-      if (outRect->bottom > imageHeight)
-      {
-        outRect->bottom = imageHeight;
-      }
-      if (outRect->right > imageWidth)
-      {
-        outRect->right = imageWidth;
-      }
-
-      for (uint16 plane = 0; plane < 3; plane++)
+      // layers can be bigger or smaller than the whole image area
+      outRect->left      = (int16)max(0, (horizTile * tileWidth - gFr->floatCoord.h));
+      outRect->right     = (int16)min(tileWidth, imageWidth - gFr->floatCoord.h);
+      uint16  OffSetH    = (uint16)max(0, gFr->floatCoord.h);
+      uint16  rectWidth  = (uint16)(outRect->right - outRect->left);
+
+      // Traverse through the planes to fill
+      for (uint16 plane = 0; plane < gData->pho.imagePlanes; plane++)
       {
         // we want one plane at a time, small memory foot print is good
-        gFr->outLoPlane = plane;
-        gFr->outHiPlane = plane;
+        int16 outplane = plane;
+        if(gData->pho.imagePlanes > 3)
+        {
+          if(plane == 0)
+          {
+            if(gFr->planes == 4)
+              continue;//ignor
+            outplane = 4;
+          }
+          else
+            outplane = plane -1;
+        }
+        gFr->outLoPlane = outplane;
+        gFr->outHiPlane = outplane;
   
         // update the gFr with our latest request
         *gResult = gFr->advanceState();
@@ -88,14 +107,12 @@
         // copy one channel at a time
         if (imageDepth == 8)
         {
-          uint8* pixel = (uint8*)gFr->outData;
-          uint16 rectHeight = (uint16)(outRect->bottom - outRect->top);
-          uint16 rectWidth = (uint16)(outRect->right - outRect->left);
+          uint8 *pixel      = (uint8*)gFr->outData;
 
           for(uint16 pixelY = 0; pixelY < rectHeight; pixelY++)
           {
             Ptr dissolve = (char *)buf + bytesPerPixel * 
-              (imageWidth * (outRect->top + pixelY) + outRect->left) + plane;
+                   (imageWidth * (OffSetH + pixelY) + OffSetV) + plane;
             for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
             {
               *pixel++ = *dissolve;
@@ -107,16 +124,15 @@
         else
         {
           // assume 16-bit
-          uint16* pixel = (uint16*)gFr->outData;
-          uint16 rectHeight = (uint16)(outRect->bottom - outRect->top);
-          uint16 rectWidth = (uint16)(outRect->right - outRect->left);
-          int bytesPerPixel2 = bytesPerPixel >> 1;
+          uint16 *pixel          = (uint16*)gFr->outData;
+          uint16  rectHeight     = (uint16)(outRect->bottom - outRect->top);
+          uint16  rectWidth      = (uint16)(outRect->right - outRect->left);
+          int     bytesPerPixel2 = bytesPerPixel >> 1;
 
           for(uint16 pixelY = 0; pixelY < rectHeight; pixelY++)
           {
             uint16 *dissolve = (uint16 *)((char *)buf + bytesPerPixel * 
-              (imageWidth * (outRect->top + pixelY) + outRect->left)
-              + 2*plane);
+                  (imageWidth * (OffSetH + pixelY) + OffSetV) + 2*plane);
             for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
             {
               // convert 0..65535 to 0..32768
@@ -135,53 +151,80 @@
 
 /**
 * Copy Image Buffer data from Photoshop to Panotool format
-* @param[in,out] buf the buffer to copy
+* Most plugins would handle a layer and its border as an image.
+* For Panotools we need to look at the image dimentions.  
+* A layer can float over a image partly in or out of the image.
+* @param[in,out] buf the Panotools image buffer to copy to
 * @return none
 **/
 int cpyPsToBuf(void *buf)
 {
+  // TODO: Actualy impliment tiling - loop through the Hort and Vert tiles retrieving a little data at a time.
+  //       for now use a tile the size of the filter rect.
+  // TODO: Use the crop feature of PanoTools to only process the data of the selection, use less memory.
+
   // some local variables for efficiency
-  int16 tileHeight = gFr->filterRect.bottom - gFr->filterRect.top;
-  int16 tileWidth = gFr->filterRect.right - gFr->filterRect.left;
-  Rect *inRect = &gFr->inRect;
-  Rect *filterRect = &gFr->filterRect;
-  int16 imageWidth = PHO.imageWidth;
-  int16 imageHeight = PHO.imageHeight;
-  int32 imageDepth = PHO.imageDepth;
-  int32 bytesPerPixel = (imageDepth/8) * 3;
+  int16 //tileHeight    = gFr->inTileHeight;// Prefered tile size.
+  //if(tileHeight == 0) 
+    tileHeight        = gFr->filterRect.bottom - gFr->filterRect.top;
+  int16 //tileWidth     = gFr->inTileWidth;
+  //if(tileWidth == 0)
+    tileWidth         = gFr->filterRect.right - gFr->filterRect.left;
+  Rect *inRect        = &gFr->inRect;
+  Rect *filterRect    = &gFr->filterRect;
+  int16 imageWidth    = gData->pho.imageWidth;
+  int16 imageHeight   = gData->pho.imageHeight;
+  int32 imageDepth    = gData->pho.imageDepth;
+  int32 bytesPerPixel = (imageDepth/8) * gData->pho.imagePlanes;
 
   // round up to the nearest horizontal and vertical tile count
-  uint16 tilesVert = (uint16)((tileHeight - 1 + imageHeight) / tileHeight);
+  uint16 tilesVert  = (uint16)((tileHeight - 1 + imageHeight) / tileHeight);
   uint16 tilesHoriz = (uint16)((tileWidth - 1 + imageWidth) / tileWidth);
 
   // Fixed numbers are 16.16 values 
   // the first 16 bits represent the whole number
   // the last 16 bits represent the fraction
-  gFr->inputRate = (int32)1 << 16;
-  gFr->maskRate = (int32)1 << 16;
+  gFr->inputRate  = (int32)1 << 16;
+  gFr->maskRate   = (int32)1 << 16;
  
   // loop through each tile makeing sure we don't go over the bounds
   // of the imageHeight or imageWidth
-  for (uint16 vertTile = 0; vertTile < tilesVert; vertTile++)
+
+  // First Vert tile with image data.
+  //uint16 vertTileFirst = (uint16)(max(0, -gFr->floatCoord.v/tileHeight));
+  //for (uint16 vertTile = vertTileFirst; vertTile < tilesVert; vertTile++)
+  uint16 vertTile = 0; 
   {
-    for (uint16 horizTile = 0; horizTile < tilesHoriz; horizTile++)
+    // layers can be bigger or smaller than whole image area but we want to copy only the area of whole image
+    inRect->top         = (int16)max(0, (vertTile * tileHeight - gFr->floatCoord.v));
+    inRect->bottom      = (int16)min(tileHeight, imageHeight - gFr->floatCoord.v);
+    uint16  OffSetV     = (uint16)max(0, gFr->floatCoord.v);
+    uint16  rectHeight  = (uint16)(inRect->bottom - inRect->top);
+
+    // First Hort tile with image data.
+    //uint16 horizTileFirst = (uint16)(max(0, gFr->floatCoord.h/tileWidth));
+    //for (uint16 horizTile = horizTileFirst; horizTile < tilesHoriz; horizTile++)
+    uint16 horizTile = 0;
     {
-      inRect->top = (int16)(vertTile * tileHeight);
-      inRect->left = (int16)(horizTile * tileWidth);
-      inRect->bottom = (int16)(inRect->top + tileHeight);
-      inRect->right = (int16)(inRect->left + tileWidth);
-
-      if (inRect->bottom > imageHeight)
-        inRect->bottom = imageHeight;
-      if (inRect->right > imageWidth)
-        inRect->right = imageWidth;
-
-      for (uint16 plane = 0; plane < 3; plane++)
+      // layers can be bigger or smaller than the whole image area
+      inRect->left       = (int16)max(0, (horizTile * tileWidth - gFr->floatCoord.h));
+      inRect->right      = (int16)min(tileWidth, imageWidth - gFr->floatCoord.h);
+      uint16  OffSetH    = (uint16)max(0, gFr->floatCoord.h);
+      uint16  rectWidth  = (uint16)(inRect->right - inRect->left);
+
+      for (uint16 plane = 0; plane < gFr->planes; plane++)
       {
         // we want one plane at a time, small memory foot print is good
         gFr->inLoPlane = plane;
         gFr->inHiPlane = plane;
-  
+        int16 outPlane = plane;
+        if(gData->pho.imagePlanes>3)
+        {
+          if(plane<3)
+            outPlane = plane +1;
+          else
+            outPlane = 0;
+        }
         // update the gFr with our latest request
         *gResult = gFr->advanceState();
         if (*gResult != noErr) 
@@ -192,18 +235,28 @@
         // copy one channel at a time
         if (imageDepth == 8)
         {
-          uint8* pixel = (uint8*)gFr->inData;
-          uint16 rectHeight = (uint16)(inRect->bottom - inRect->top);
-          uint16 rectWidth = (uint16)(inRect->right - inRect->left);
+          uint8 *pixel      = (uint8*)gFr->inData;
 
           for(uint16 pixelY = 0; pixelY < rectHeight; pixelY++)
           {
             Ptr dissolve = (char *)buf + bytesPerPixel * 
-              (imageWidth * (inRect->top + pixelY) + inRect->left) + plane;
-            for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
-            {
-              *dissolve = *pixel++;
-              dissolve += bytesPerPixel;
+                  (imageWidth * (OffSetH + pixelY) + OffSetV) + outPlane;
+            if(plane <4)
+            {
+              for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
+              {
+                *dissolve = *pixel++;
+                dissolve += bytesPerPixel;
+              }
+            }
+            else
+            {
+              for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
+              {
+                *dissolve = min((char)*dissolve, (char)*pixel);
+                pixel++;
+                dissolve += bytesPerPixel;
+              }
             }
             pixel += gFr->inRowBytes - rectWidth;
           }//pixelY
@@ -211,22 +264,30 @@
         else
         {
           // assume 16-bit
-          uint16* pixel = (uint16*)gFr->inData;
-          uint16 rectHeight = (uint16)(inRect->bottom - inRect->top);
-          uint16 rectWidth = (uint16)(inRect->right - inRect->left);
-          int bytesPerPixel2 = bytesPerPixel >> 1;
+          uint16 *pixel           = (uint16*)gFr->inData;
+          int     bytesPerPixel2  = bytesPerPixel >> 1;
 
           for(uint16 pixelY = 0; pixelY < rectHeight; pixelY++)
           {
-            uint16 *dissolve = (uint16 *)((char *)buf + 
-              bytesPerPixel * 
-              (imageWidth * (inRect->top + pixelY) + inRect->left)
-              + 2*plane);
-            for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
-            {
-              // convert 0..32768 to 0..65535
-              *dissolve = (*pixel++ * 65535U + 16384U) >> 15;
-              dissolve += bytesPerPixel2;
+            uint16 *dissolve = (uint16 *)((char *)buf + bytesPerPixel * 
+                  (imageWidth * (OffSetH + pixelY) + OffSetV) + 2*outPlane);
+            if(plane <4)
+            {
+              for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
+              {
+                // convert 0..32768 to 0..65535
+                *dissolve = ((uint16)*pixel++ * 65535U + 16384U) >> 15;
+                dissolve += bytesPerPixel2;
+              }
+            }
+            else
+            {
+              for(uint16 pixelX = 0; pixelX < rectWidth; pixelX++)
+              {
+                // convert 0..32768 to 0..65535
+                *dissolve = min(*dissolve , (*pixel++ * 65535U + 16384U) >> 15);
+                dissolve += bytesPerPixel2;
+              }
             }
             pixel += (gFr->inRowBytes - 2*rectWidth) >> 1;
           }//pixelY