/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

///////////////////////////////////////////////////
// Blend.cpp
// $Id: Blend.cpp,v 1.22 2011/06/24 04:22:14 mbansal Exp $

#include <string.h>

#include "Interp.h"
#include "Blend.h"

#include "Geometry.h"
#include "trsMatrix.h"

#include "Log.h"
#define LOG_TAG "BLEND"

Blend::Blend()
{
  m_wb.blendingType = BLEND_TYPE_NONE;
}

Blend::~Blend()
{
    if (m_pFrameVPyr) free(m_pFrameVPyr);
    if (m_pFrameUPyr) free(m_pFrameUPyr);
    if (m_pFrameYPyr) free(m_pFrameYPyr);
}

int Blend::initialize(int blendingType, int stripType, int frame_width, int frame_height)
{
    this->width = frame_width;
    this->height = frame_height;
    this->m_wb.blendingType = blendingType;
    this->m_wb.stripType = stripType;

    m_wb.blendRange = m_wb.blendRangeUV = BLEND_RANGE_DEFAULT;
    m_wb.nlevs = m_wb.blendRange;
    m_wb.nlevsC = m_wb.blendRangeUV;

    if (m_wb.nlevs <= 0) m_wb.nlevs = 1; // Need levels for YUV processing
    if (m_wb.nlevsC > m_wb.nlevs) m_wb.nlevsC = m_wb.nlevs;

    m_wb.roundoffOverlap = 1.5;

    m_pFrameYPyr = NULL;
    m_pFrameUPyr = NULL;
    m_pFrameVPyr = NULL;

    m_pFrameYPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevs, (unsigned short) width, (unsigned short) height, BORDER);
    m_pFrameUPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevsC, (unsigned short) (width), (unsigned short) (height), BORDER);
    m_pFrameVPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevsC, (unsigned short) (width), (unsigned short) (height), BORDER);

    if (!m_pFrameYPyr || !m_pFrameUPyr || !m_pFrameVPyr)
    {
        LOGE("Error: Could not allocate pyramids for blending");
        return BLEND_RET_ERROR_MEMORY;
    }

    return BLEND_RET_OK;
}

inline double max(double a, double b) { return a > b ? a : b; }
inline double min(double a, double b) { return a < b ? a : b; }

void Blend::AlignToMiddleFrame(MosaicFrame **frames, int frames_size)
{
    // Unwarp this frame and Warp the others to match
    MosaicFrame *mb = NULL;
    MosaicFrame *ref = frames[int(frames_size/2)];    // Middle frame

    double invtrs[3][3];
    inv33d(ref->trs, invtrs);

    for(int mfit = 0; mfit < frames_size; mfit++)
    {
        mb = frames[mfit];
        double temp[3][3];
        mult33d(temp, invtrs, mb->trs);
        memcpy(mb->trs, temp, sizeof(temp));
        normProjMat33d(mb->trs);
    }
}

int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes,
        int frames_size,
        ImageType &imageMosaicYVU, int &mosaicWidth, int &mosaicHeight,
        float &progress, bool &cancelComputation)
{
    int ret;
    int numCenters;

    MosaicFrame **frames;

    // For THIN strip mode, accept all frames for blending
    if (m_wb.stripType == STRIP_TYPE_THIN)
    {
        frames = oframes;
    }
    else // For WIDE strip mode, first select the relevant frames to blend.
    {
        SelectRelevantFrames(oframes, frames_size, rframes, frames_size);
        frames = rframes;
    }

    ComputeBlendParameters(frames, frames_size, true);
    numCenters = frames_size;

    if (numCenters == 0)
    {
        LOGE("Error: No frames to blend");
        return BLEND_RET_ERROR;
    }

    if (!(m_AllSites = m_Triangulator.allocMemory(numCenters)))
    {
        return BLEND_RET_ERROR_MEMORY;
    }

    // Bounding rectangle (real numbers) of the final mosaic computed by projecting
    // each input frame into the mosaic coordinate system.
    BlendRect global_rect;

    global_rect.lft = global_rect.bot = 2e30; // min values
    global_rect.rgt = global_rect.top = -2e30; // max values
    MosaicFrame *mb = NULL;
    double halfwidth = width / 2.0;
    double halfheight = height / 2.0;

    double z, x0, y0, x1, y1, x2, y2, x3, y3;

    // Corners of the left-most and right-most frames respectively in the
    // mosaic coordinate system.
    double xLeftCorners[2] = {2e30, 2e30};
    double xRightCorners[2] = {-2e30, -2e30};

    // Corners of the top-most and bottom-most frames respectively in the
    // mosaic coordinate system.
    double yTopCorners[2] = {2e30, 2e30};
    double yBottomCorners[2] = {-2e30, -2e30};


    // Determine the extents of the final mosaic
    CSite *csite = m_AllSites ;
    for(int mfit = 0; mfit < frames_size; mfit++)
    {
        mb = frames[mfit];

        // Compute clipping for this frame's rect
        FrameToMosaicRect(mb->width, mb->height, mb->trs, mb->brect);
        // Clip global rect using this frame's rect
        ClipRect(mb->brect, global_rect);

        // Calculate the corner points
        FrameToMosaic(mb->trs, 0.0,             0.0,            x0, y0);
        FrameToMosaic(mb->trs, 0.0,             mb->height-1.0, x1, y1);
        FrameToMosaic(mb->trs, mb->width-1.0,   mb->height-1.0, x2, y2);
        FrameToMosaic(mb->trs, mb->width-1.0,   0.0,            x3, y3);

        if(x0 < xLeftCorners[0] || x1 < xLeftCorners[1])    // If either of the left corners is lower
        {
            xLeftCorners[0] = x0;
            xLeftCorners[1] = x1;
        }

        if(x3 > xRightCorners[0] || x2 > xRightCorners[1])    // If either of the right corners is higher
        {
            xRightCorners[0] = x3;
            xRightCorners[1] = x2;
        }

        if(y0 < yTopCorners[0] || y3 < yTopCorners[1])    // If either of the top corners is lower
        {
            yTopCorners[0] = y0;
            yTopCorners[1] = y3;
        }

        if(y1 > yBottomCorners[0] || y2 > yBottomCorners[1])    // If either of the bottom corners is higher
        {
            yBottomCorners[0] = y1;
            yBottomCorners[1] = y2;
        }


        // Compute the centroid of the warped region
        FindQuadCentroid(x0, y0, x1, y1, x2, y2, x3, y3, csite->getVCenter().x, csite->getVCenter().y);

        csite->setMb(mb);
        csite++;
    }

    // Get origin and sizes

    // Bounding rectangle (int numbers) of the final mosaic computed by projecting
    // each input frame into the mosaic coordinate system.
    MosaicRect fullRect;

    fullRect.left = (int) floor(global_rect.lft); // min-x
    fullRect.top = (int) floor(global_rect.bot);  // min-y
    fullRect.right = (int) ceil(global_rect.rgt); // max-x
    fullRect.bottom = (int) ceil(global_rect.top);// max-y
    Mwidth = (unsigned short) (fullRect.right - fullRect.left + 1);
    Mheight = (unsigned short) (fullRect.bottom - fullRect.top + 1);

    int xLeftMost, xRightMost;
    int yTopMost, yBottomMost;

    // Rounding up, so that we don't include the gray border.
    xLeftMost = max(0, max(xLeftCorners[0], xLeftCorners[1]) - fullRect.left + 1);
    xRightMost = min(Mwidth - 1, min(xRightCorners[0], xRightCorners[1]) - fullRect.left - 1);

    yTopMost = max(0, max(yTopCorners[0], yTopCorners[1]) - fullRect.top + 1);
    yBottomMost = min(Mheight - 1, min(yBottomCorners[0], yBottomCorners[1]) - fullRect.top - 1);

    if (xRightMost <= xLeftMost || yBottomMost <= yTopMost)
    {
        LOGE("RunBlend: aborting -consistency check failed,"
             "(xLeftMost, xRightMost, yTopMost, yBottomMost): (%d, %d, %d, %d)",
             xLeftMost, xRightMost, yTopMost, yBottomMost);
        return BLEND_RET_ERROR;
    }

    // Make sure image width is multiple of 4
    Mwidth = (unsigned short) ((Mwidth + 3) & ~3);
    Mheight = (unsigned short) ((Mheight + 3) & ~3);    // Round up.

    ret = MosaicSizeCheck(LIMIT_SIZE_MULTIPLIER, LIMIT_HEIGHT_MULTIPLIER);
    if (ret != BLEND_RET_OK)
    {
       LOGE("RunBlend: aborting - mosaic size check failed, "
            "(frame_width, frame_height) vs (mosaic_width, mosaic_height): "
            "(%d, %d) vs (%d, %d)", width, height, Mwidth, Mheight);
       return ret;
    }

    LOGI("Allocate mosaic image for blending - size: %d x %d", Mwidth, Mheight);
    YUVinfo *imgMos = YUVinfo::allocateImage(Mwidth, Mheight);
    if (imgMos == NULL)
    {
        LOGE("RunBlend: aborting - couldn't alloc %d x %d mosaic image", Mwidth, Mheight);
        return BLEND_RET_ERROR_MEMORY;
    }

    // Set the Y image to 255 so we can distinguish when frame idx are written to it
    memset(imgMos->Y.ptr[0], 255, (imgMos->Y.width * imgMos->Y.height));
    // Set the v and u images to black
    memset(imgMos->V.ptr[0], 128, (imgMos->V.width * imgMos->V.height) << 1);

    // Do the triangulation.  It returns a sorted list of edges
    SEdgeVector *edge;
    int n = m_Triangulator.triangulate(&edge, numCenters, width, height);
    m_Triangulator.linkNeighbors(edge, n, numCenters);

    // Bounding rectangle that determines the positioning of the rectangle that is
    // cropped out of the computed mosaic to get rid of the gray borders.
    MosaicRect cropping_rect;

    if (m_wb.horizontal)
    {
        cropping_rect.left = xLeftMost;
        cropping_rect.right = xRightMost;
    }
    else
    {
        cropping_rect.top = yTopMost;
        cropping_rect.bottom = yBottomMost;
    }

    // Do merging and blending :
    ret = DoMergeAndBlend(frames, numCenters, width, height, *imgMos, fullRect,
            cropping_rect, progress, cancelComputation);

    if (m_wb.blendingType == BLEND_TYPE_HORZ)
        CropFinalMosaic(*imgMos, cropping_rect);


    m_Triangulator.freeMemory();    // note: can be called even if delaunay_alloc() wasn't successful

    imageMosaicYVU = imgMos->Y.ptr[0];


    if (m_wb.blendingType == BLEND_TYPE_HORZ)
    {
        mosaicWidth = cropping_rect.right - cropping_rect.left + 1;
        mosaicHeight = cropping_rect.bottom - cropping_rect.top + 1;
    }
    else
    {
        mosaicWidth = Mwidth;
        mosaicHeight = Mheight;
    }

    return ret;
}

int Blend::MosaicSizeCheck(float sizeMultiplier, float heightMultiplier) {
   if (Mwidth < width || Mheight < height) {
        return BLEND_RET_ERROR;
    }

   if ((Mwidth * Mheight) > (width * height * sizeMultiplier)) {
         return BLEND_RET_ERROR;
   }

   // We won't do blending for the cases where users swing the device too much
   // in the secondary direction. We use a short side to determine the
   // secondary direction because users may hold the device in landsape
   // or portrait.
   int shortSide = min(Mwidth, Mheight);
   if (shortSide > height * heightMultiplier) {
       return BLEND_RET_ERROR;
   }

   return BLEND_RET_OK;
}

int Blend::FillFramePyramid(MosaicFrame *mb)
{
    ImageType mbY, mbU, mbV;
    // Lay this image, centered into the temporary buffer
    mbY = mb->image;
    mbU = mb->getU();
    mbV = mb->getV();

    int h, w;

    for(h=0; h<height; h++)
    {
        ImageTypeShort yptr = m_pFrameYPyr->ptr[h];
        ImageTypeShort uptr = m_pFrameUPyr->ptr[h];
        ImageTypeShort vptr = m_pFrameVPyr->ptr[h];

        for(w=0; w<width; w++)
        {
            yptr[w] = (short) ((*(mbY++)) << 3);
            uptr[w] = (short) ((*(mbU++)) << 3);
            vptr[w] = (short) ((*(mbV++)) << 3);
        }
    }

    // Spread the image through the border
    PyramidShort::BorderSpread(m_pFrameYPyr, BORDER, BORDER, BORDER, BORDER);
    PyramidShort::BorderSpread(m_pFrameUPyr, BORDER, BORDER, BORDER, BORDER);
    PyramidShort::BorderSpread(m_pFrameVPyr, BORDER, BORDER, BORDER, BORDER);

    // Generate Laplacian pyramids
    if (!PyramidShort::BorderReduce(m_pFrameYPyr, m_wb.nlevs) || !PyramidShort::BorderExpand(m_pFrameYPyr, m_wb.nlevs, -1) ||
            !PyramidShort::BorderReduce(m_pFrameUPyr, m_wb.nlevsC) || !PyramidShort::BorderExpand(m_pFrameUPyr, m_wb.nlevsC, -1) ||
            !PyramidShort::BorderReduce(m_pFrameVPyr, m_wb.nlevsC) || !PyramidShort::BorderExpand(m_pFrameVPyr, m_wb.nlevsC, -1))
    {
        LOGE("Error: Could not generate Laplacian pyramids");
        return BLEND_RET_ERROR;
    }
    else
    {
        return BLEND_RET_OK;
    }
}

int Blend::DoMergeAndBlend(MosaicFrame **frames, int nsite,
             int width, int height, YUVinfo &imgMos, MosaicRect &rect,
             MosaicRect &cropping_rect, float &progress, bool &cancelComputation)
{
    m_pMosaicYPyr = NULL;
    m_pMosaicUPyr = NULL;
    m_pMosaicVPyr = NULL;

    m_pMosaicYPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevs,(unsigned short)rect.Width(),(unsigned short)rect.Height(),BORDER);
    m_pMosaicUPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevsC,(unsigned short)rect.Width(),(unsigned short)rect.Height(),BORDER);
    m_pMosaicVPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevsC,(unsigned short)rect.Width(),(unsigned short)rect.Height(),BORDER);
    if (!m_pMosaicYPyr || !m_pMosaicUPyr || !m_pMosaicVPyr)
    {
      LOGE("Error: Could not allocate pyramids for blending");
      return BLEND_RET_ERROR_MEMORY;
    }

    MosaicFrame *mb;

    CSite *esite = m_AllSites + nsite;
    int site_idx;

    // First go through each frame and for each mosaic pixel determine which frame it should come from
    site_idx = 0;
    for(CSite *csite = m_AllSites; csite < esite; csite++)
    {
        if(cancelComputation)
        {
            if (m_pMosaicVPyr) free(m_pMosaicVPyr);
            if (m_pMosaicUPyr) free(m_pMosaicUPyr);
            if (m_pMosaicYPyr) free(m_pMosaicYPyr);
            return BLEND_RET_CANCELLED;
        }

        mb = csite->getMb();

        mb->vcrect = mb->brect;
        ClipBlendRect(csite, mb->vcrect);

        ComputeMask(csite, mb->vcrect, mb->brect, rect, imgMos, site_idx);

        site_idx++;
    }

    ////////// imgMos.Y, imgMos.V, imgMos.U are used as follows //////////////
    ////////////////////// THIN STRIP MODE ///////////////////////////////////

    // imgMos.Y is used to store the index of the image from which each pixel
    // in the output mosaic can be read out for the thin-strip mode. Thus,
    // there is no special handling for pixels around the seam. Also, imgMos.Y
    // is set to 255 wherever we can't get its value from any input image e.g.
    // in the gray border areas. imgMos.V and imgMos.U are set to 128 for the
    // thin-strip mode.

    ////////////////////// WIDE STRIP MODE ///////////////////////////////////

    // imgMos.Y is used the same way as the thin-strip mode.
    // imgMos.V is used to store the index of the neighboring image which
    // should contribute to the color of an output pixel in a band around
    // the seam. Thus, in this band, we will crossfade between the color values
    // from the image index imgMos.Y and image index imgMos.V. imgMos.U is
    // used to store the weight (multiplied by 100) that each image will
    // contribute to the blending process. Thus, we start at 99% contribution
    // from the first image, then go to 50% contribution from each image at
    // the seam. Then, the contribution from the second image goes up to 99%.

    // For WIDE mode, set the pixel masks to guide the blender to cross-fade
    // between the images on either side of each seam:
    if (m_wb.stripType == STRIP_TYPE_WIDE)
    {
        if(m_wb.horizontal)
        {
            // Set the number of pixels around the seam to cross-fade between
            // the two component images,
            int tw = STRIP_CROSS_FADE_WIDTH_PXLS;

            // Proceed with the image index calculation for cross-fading
            // only if the cross-fading width is larger than 0
            if (tw > 0)
            {
                for(int y = 0; y < imgMos.Y.height; y++)
                {
                    // Since we compare two adjecant pixels to determine
                    // whether there is a seam, the termination condition of x
                    // is set to imgMos.Y.width - tw, so that x+1 below
                    // won't exceed the imgMos' boundary.
                    for(int x = tw; x < imgMos.Y.width - tw; )
                    {
                        // Determine where the seam is...
                        if (imgMos.Y.ptr[y][x] != imgMos.Y.ptr[y][x+1] &&
                                imgMos.Y.ptr[y][x] != 255 &&
                                imgMos.Y.ptr[y][x+1] != 255)
                        {
                            // Find the image indices on both sides of the seam
                            unsigned char idx1 = imgMos.Y.ptr[y][x];
                            unsigned char idx2 = imgMos.Y.ptr[y][x+1];

                            for (int o = tw; o >= 0; o--)
                            {
                                // Set the image index to use for cross-fading
                                imgMos.V.ptr[y][x - o] = idx2;
                                // Set the intensity weights to use for cross-fading
                                imgMos.U.ptr[y][x - o] = 50 + (99 - 50) * o / tw;
                            }

                            for (int o = 1; o <= tw; o++)
                            {
                                // Set the image index to use for cross-fading
                                imgMos.V.ptr[y][x + o] = idx1;
                                // Set the intensity weights to use for cross-fading
                                imgMos.U.ptr[y][x + o] = imgMos.U.ptr[y][x - o];
                            }

                            x += (tw + 1);
                        }
                        else
                        {
                            x++;
                        }
                    }
                }
            }
        }
        else
        {
            // Set the number of pixels around the seam to cross-fade between
            // the two component images,
            int tw = STRIP_CROSS_FADE_WIDTH_PXLS;

            // Proceed with the image index calculation for cross-fading
            // only if the cross-fading width is larger than 0
            if (tw > 0)
            {
                for(int x = 0; x < imgMos.Y.width; x++)
                {
                    // Since we compare two adjecant pixels to determine
                    // whether there is a seam, the termination condition of y
                    // is set to imgMos.Y.height - tw, so that y+1 below
                    // won't exceed the imgMos' boundary.
                    for(int y = tw; y < imgMos.Y.height - tw; )
                    {
                        // Determine where the seam is...
                        if (imgMos.Y.ptr[y][x] != imgMos.Y.ptr[y+1][x] &&
                                imgMos.Y.ptr[y][x] != 255 &&
                                imgMos.Y.ptr[y+1][x] != 255)
                        {
                            // Find the image indices on both sides of the seam
                            unsigned char idx1 = imgMos.Y.ptr[y][x];
                            unsigned char idx2 = imgMos.Y.ptr[y+1][x];

                            for (int o = tw; o >= 0; o--)
                            {
                                // Set the image index to use for cross-fading
                                imgMos.V.ptr[y - o][x] = idx2;
                                // Set the intensity weights to use for cross-fading
                                imgMos.U.ptr[y - o][x] = 50 + (99 - 50) * o / tw;
                            }

                            for (int o = 1; o <= tw; o++)
                            {
                                // Set the image index to use for cross-fading
                                imgMos.V.ptr[y + o][x] = idx1;
                                // Set the intensity weights to use for cross-fading
                                imgMos.U.ptr[y + o][x] = imgMos.U.ptr[y - o][x];
                            }

                            y += (tw + 1);
                        }
                        else
                        {
                            y++;
                        }
                    }
                }
            }
        }

    }

    // Now perform the actual blending using the frame assignment determined above
    site_idx = 0;
    for(CSite *csite = m_AllSites; csite < esite; csite++)
    {
        if(cancelComputation)
        {
            if (m_pMosaicVPyr) free(m_pMosaicVPyr);
            if (m_pMosaicUPyr) free(m_pMosaicUPyr);
            if (m_pMosaicYPyr) free(m_pMosaicYPyr);
            return BLEND_RET_CANCELLED;
        }

        mb = csite->getMb();


        if(FillFramePyramid(mb)!=BLEND_RET_OK)
            return BLEND_RET_ERROR;

        ProcessPyramidForThisFrame(csite, mb->vcrect, mb->brect, rect, imgMos, mb->trs, site_idx);

        progress += TIME_PERCENT_BLEND/nsite;

        site_idx++;
    }


    // Blend
    PerformFinalBlending(imgMos, cropping_rect);

    if (cropping_rect.Width() <= 0 || cropping_rect.Height() <= 0)
    {
        LOGE("Size of the cropping_rect is invalid - (width, height): (%d, %d)",
                cropping_rect.Width(), cropping_rect.Height());
        return BLEND_RET_ERROR;
    }

    if (m_pMosaicVPyr) free(m_pMosaicVPyr);
    if (m_pMosaicUPyr) free(m_pMosaicUPyr);
    if (m_pMosaicYPyr) free(m_pMosaicYPyr);

    progress += TIME_PERCENT_FINAL;

    return BLEND_RET_OK;
}

void Blend::CropFinalMosaic(YUVinfo &imgMos, MosaicRect &cropping_rect)
{
    int i, j, k;
    ImageType yimg;
    ImageType uimg;
    ImageType vimg;


    yimg = imgMos.Y.ptr[0];
    uimg = imgMos.U.ptr[0];
    vimg = imgMos.V.ptr[0];

    k = 0;
    for (j = cropping_rect.top; j <= cropping_rect.bottom; j++)
    {
        for (i = cropping_rect.left; i <= cropping_rect.right; i++)
        {
            yimg[k] = yimg[j*imgMos.Y.width+i];
            k++;
        }
    }
    for (j = cropping_rect.top; j <= cropping_rect.bottom; j++)
    {
       for (i = cropping_rect.left; i <= cropping_rect.right; i++)
        {
            yimg[k] = vimg[j*imgMos.Y.width+i];
            k++;
        }
    }
    for (j = cropping_rect.top; j <= cropping_rect.bottom; j++)
    {
       for (i = cropping_rect.left; i <= cropping_rect.right; i++)
        {
            yimg[k] = uimg[j*imgMos.Y.width+i];
            k++;
        }
    }
}

int Blend::PerformFinalBlending(YUVinfo &imgMos, MosaicRect &cropping_rect)
{
    if (!PyramidShort::BorderExpand(m_pMosaicYPyr, m_wb.nlevs, 1) || !PyramidShort::BorderExpand(m_pMosaicUPyr, m_wb.nlevsC, 1) ||
        !PyramidShort::BorderExpand(m_pMosaicVPyr, m_wb.nlevsC, 1))
    {
      LOGE("Error: Could not BorderExpand!");
      return BLEND_RET_ERROR;
    }

    ImageTypeShort myimg;
    ImageTypeShort muimg;
    ImageTypeShort mvimg;
    ImageType yimg;
    ImageType uimg;
    ImageType vimg;

    int cx = (int)imgMos.Y.width/2;
    int cy = (int)imgMos.Y.height/2;

    // 2D boolean array that contains true wherever the mosaic image data is
    // invalid (i.e. in the gray border).
    bool **b = new bool*[imgMos.Y.height];

    for(int j=0; j<imgMos.Y.height; j++)
    {
        b[j] = new bool[imgMos.Y.width];
    }

    // Copy the resulting image into the full image using the mask
    int i, j;

    yimg = imgMos.Y.ptr[0];
    uimg = imgMos.U.ptr[0];
    vimg = imgMos.V.ptr[0];

    for (j = 0; j < imgMos.Y.height; j++)
    {
        myimg = m_pMosaicYPyr->ptr[j];
        muimg = m_pMosaicUPyr->ptr[j];
        mvimg = m_pMosaicVPyr->ptr[j];

        for (i = 0; i<imgMos.Y.width; i++)
        {
            // A final mask was set up previously,
            // if the value is zero skip it, otherwise replace it.
            if (*yimg <255)
            {
                short value = (short) ((*myimg) >> 3);
                if (value < 0) value = 0;
                else if (value > 255) value = 255;
                *yimg = (unsigned char) value;

                value = (short) ((*muimg) >> 3);
                if (value < 0) value = 0;
                else if (value > 255) value = 255;
                *uimg = (unsigned char) value;

                value = (short) ((*mvimg) >> 3);
                if (value < 0) value = 0;
                else if (value > 255) value = 255;
                *vimg = (unsigned char) value;

                b[j][i] = false;

            }
            else
            {   // set border color in here
                *yimg = (unsigned char) 96;
                *uimg = (unsigned char) 128;
                *vimg = (unsigned char) 128;

                b[j][i] = true;
            }

            yimg++;
            uimg++;
            vimg++;
            myimg++;
            muimg++;
            mvimg++;
        }
    }

    if(m_wb.horizontal)
    {
        //Scan through each row and increment top if the row contains any gray
        for (j = 0; j < imgMos.Y.height; j++)
        {
            for (i = cropping_rect.left; i < cropping_rect.right; i++)
            {
                if (b[j][i])
                {
                    break; // to next row
                }
            }

            if (i == cropping_rect.right)   //no gray pixel in this row!
            {
                cropping_rect.top = j;
                break;
            }
        }

        //Scan through each row and decrement bottom if the row contains any gray
        for (j = imgMos.Y.height-1; j >= 0; j--)
        {
            for (i = cropping_rect.left; i < cropping_rect.right; i++)
            {
                if (b[j][i])
                {
                    break; // to next row
                }
            }

            if (i == cropping_rect.right)   //no gray pixel in this row!
            {
                cropping_rect.bottom = j;
                break;
            }
        }
    }
    else // Vertical Mosaic
    {
        //Scan through each column and increment left if the column contains any gray
        for (i = 0; i < imgMos.Y.width; i++)
        {
            for (j = cropping_rect.top; j < cropping_rect.bottom; j++)
            {
                if (b[j][i])
                {
                    break; // to next column
                }
            }

            if (j == cropping_rect.bottom)   //no gray pixel in this column!
            {
                cropping_rect.left = i;
                break;
            }
        }

        //Scan through each column and decrement right if the column contains any gray
        for (i = imgMos.Y.width-1; i >= 0; i--)
        {
            for (j = cropping_rect.top; j < cropping_rect.bottom; j++)
            {
                if (b[j][i])
                {
                    break; // to next column
                }
            }

            if (j == cropping_rect.bottom)   //no gray pixel in this column!
            {
                cropping_rect.right = i;
                break;
            }
        }

    }

    RoundingCroppingSizeToMultipleOf8(cropping_rect);

    for(int j=0; j<imgMos.Y.height; j++)
    {
        delete b[j];
    }

    delete b;

    return BLEND_RET_OK;
}

void Blend::RoundingCroppingSizeToMultipleOf8(MosaicRect &rect) {
    int height = rect.bottom - rect.top + 1;
    int residue = height & 7;
    rect.bottom -= residue;

    int width = rect.right - rect.left + 1;
    residue = width & 7;
    rect.right -= residue;
}

void Blend::ComputeMask(CSite *csite, BlendRect &vcrect, BlendRect &brect, MosaicRect &rect, YUVinfo &imgMos, int site_idx)
{
    PyramidShort *dptr = m_pMosaicYPyr;

    int nC = m_wb.nlevsC;
    int l = (int) ((vcrect.lft - rect.left));
    int b = (int) ((vcrect.bot - rect.top));
    int r = (int) ((vcrect.rgt - rect.left));
    int t = (int) ((vcrect.top - rect.top));

    if (vcrect.lft == brect.lft)
        l = (l <= 0) ? -BORDER : l - BORDER;
    else if (l < -BORDER)
        l = -BORDER;

    if (vcrect.bot == brect.bot)
        b = (b <= 0) ? -BORDER : b - BORDER;
    else if (b < -BORDER)
        b = -BORDER;

    if (vcrect.rgt == brect.rgt)
        r = (r >= dptr->width) ? dptr->width + BORDER - 1 : r + BORDER;
    else if (r >= dptr->width + BORDER)
        r = dptr->width + BORDER - 1;

    if (vcrect.top == brect.top)
        t = (t >= dptr->height) ? dptr->height + BORDER - 1 : t + BORDER;
    else if (t >= dptr->height + BORDER)
        t = dptr->height + BORDER - 1;

    // Walk the Region of interest and populate the pyramid
    for (int j = b; j <= t; j++)
    {
        int jj = j;
        double sj = jj + rect.top;

        for (int i = l; i <= r; i++)
        {
            int ii = i;
            // project point and then triangulate to neighbors
            double si = ii + rect.left;

            double dself = hypotSq(csite->getVCenter().x - si, csite->getVCenter().y - sj);
            int inMask = ((unsigned) ii < imgMos.Y.width &&
                    (unsigned) jj < imgMos.Y.height) ? 1 : 0;

            if(!inMask)
                continue;

            // scan the neighbors to see if this is a valid position
            unsigned char mask = (unsigned char) 255;
            SEdgeVector *ce;
            int ecnt;
            for (ce = csite->getNeighbor(), ecnt = csite->getNumNeighbors(); ecnt--; ce++)
            {
                double d1 = hypotSq(m_AllSites[ce->second].getVCenter().x - si,
                        m_AllSites[ce->second].getVCenter().y - sj);
                if (d1 < dself)
                {
                    break;
                }
            }

            if (ecnt >= 0) continue;

            imgMos.Y.ptr[jj][ii] = (unsigned char)site_idx;
        }
    }
}

void Blend::ProcessPyramidForThisFrame(CSite *csite, BlendRect &vcrect, BlendRect &brect, MosaicRect &rect, YUVinfo &imgMos, double trs[3][3], int site_idx)
{
    // Put the Region of interest (for all levels) into m_pMosaicYPyr
    double inv_trs[3][3];
    inv33d(trs, inv_trs);

    // Process each pyramid level
    PyramidShort *sptr = m_pFrameYPyr;
    PyramidShort *suptr = m_pFrameUPyr;
    PyramidShort *svptr = m_pFrameVPyr;

    PyramidShort *dptr = m_pMosaicYPyr;
    PyramidShort *duptr = m_pMosaicUPyr;
    PyramidShort *dvptr = m_pMosaicVPyr;

    int dscale = 0; // distance scale for the current level
    int nC = m_wb.nlevsC;
    for (int n = m_wb.nlevs; n--; dscale++, dptr++, sptr++, dvptr++, duptr++, svptr++, suptr++, nC--)
    {
        int l = (int) ((vcrect.lft - rect.left) / (1 << dscale));
        int b = (int) ((vcrect.bot - rect.top) / (1 << dscale));
        int r = (int) ((vcrect.rgt - rect.left) / (1 << dscale) + .5);
        int t = (int) ((vcrect.top - rect.top) / (1 << dscale) + .5);

        if (vcrect.lft == brect.lft)
            l = (l <= 0) ? -BORDER : l - BORDER;
        else if (l < -BORDER)
            l = -BORDER;

        if (vcrect.bot == brect.bot)
            b = (b <= 0) ? -BORDER : b - BORDER;
        else if (b < -BORDER)
            b = -BORDER;

        if (vcrect.rgt == brect.rgt)
            r = (r >= dptr->width) ? dptr->width + BORDER - 1 : r + BORDER;
        else if (r >= dptr->width + BORDER)
            r = dptr->width + BORDER - 1;

        if (vcrect.top == brect.top)
            t = (t >= dptr->height) ? dptr->height + BORDER - 1 : t + BORDER;
        else if (t >= dptr->height + BORDER)
            t = dptr->height + BORDER - 1;

        // Walk the Region of interest and populate the pyramid
        for (int j = b; j <= t; j++)
        {
            int jj = (j << dscale);
            double sj = jj + rect.top;

            for (int i = l; i <= r; i++)
            {
                int ii = (i << dscale);
                // project point and then triangulate to neighbors
                double si = ii + rect.left;

                int inMask = ((unsigned) ii < imgMos.Y.width &&
                        (unsigned) jj < imgMos.Y.height) ? 1 : 0;

                if(inMask && imgMos.Y.ptr[jj][ii] != site_idx &&
                        imgMos.V.ptr[jj][ii] != site_idx &&
                        imgMos.Y.ptr[jj][ii] != 255)
                    continue;

                // Setup weights for cross-fading
                // Weight of the intensity already in the output pixel
                double wt0 = 0.0;
                // Weight of the intensity from the input pixel (current frame)
                double wt1 = 1.0;

                if (m_wb.stripType == STRIP_TYPE_WIDE)
                {
                    if(inMask && imgMos.Y.ptr[jj][ii] != 255)
                    {
                        // If not on a seam OR pyramid level exceeds
                        // maximum level for cross-fading.
                        if((imgMos.V.ptr[jj][ii] == 128) ||
                            (dscale > STRIP_CROSS_FADE_MAX_PYR_LEVEL))
                        {
                            wt0 = 0.0;
                            wt1 = 1.0;
                        }
                        else
                        {
                            wt0 = 1.0;
                            wt1 = ((imgMos.Y.ptr[jj][ii] == site_idx) ?
                                    (double)imgMos.U.ptr[jj][ii] / 100.0 :
                                    1.0 - (double)imgMos.U.ptr[jj][ii] / 100.0);
                        }
                    }
                }

                // Project this mosaic point into the original frame coordinate space
                double xx, yy;

                MosaicToFrame(inv_trs, si, sj, xx, yy);

                if (xx < 0.0 || yy < 0.0 || xx > width - 1.0 || yy > height - 1.0)
                {
                    if(inMask)
                    {
                        imgMos.Y.ptr[jj][ii] = 255;
                        wt0 = 0.0f;
                        wt1 = 1.0f;
                    }
                }

                xx /= (1 << dscale);
                yy /= (1 << dscale);


                int x1 = (xx >= 0.0) ? (int) xx : (int) floor(xx);
                int y1 = (yy >= 0.0) ? (int) yy : (int) floor(yy);

                // Final destination in extended pyramid
#ifndef LINEAR_INTERP
                if(inSegment(x1, sptr->width, BORDER-1) &&
                        inSegment(y1, sptr->height, BORDER-1))
                {
                    double xfrac = xx - x1;
                    double yfrac = yy - y1;
                    dptr->ptr[j][i] = (short) (wt0 * dptr->ptr[j][i] + .5 +
                            wt1 * ciCalc(sptr, x1, y1, xfrac, yfrac));
                    if (dvptr >= m_pMosaicVPyr && nC > 0)
                    {
                        duptr->ptr[j][i] = (short) (wt0 * duptr->ptr[j][i] + .5 +
                                wt1 * ciCalc(suptr, x1, y1, xfrac, yfrac));
                        dvptr->ptr[j][i] = (short) (wt0 * dvptr->ptr[j][i] + .5 +
                                wt1 * ciCalc(svptr, x1, y1, xfrac, yfrac));
                    }
                }
#else
                if(inSegment(x1, sptr->width, BORDER) && inSegment(y1, sptr->height, BORDER))
                {
                    int x2 = x1 + 1;
                    int y2 = y1 + 1;
                    double xfrac = xx - x1;
                    double yfrac = yy - y1;
                    double y1val = sptr->ptr[y1][x1] +
                        (sptr->ptr[y1][x2] - sptr->ptr[y1][x1]) * xfrac;
                    double y2val = sptr->ptr[y2][x1] +
                        (sptr->ptr[y2][x2] - sptr->ptr[y2][x1]) * xfrac;
                    dptr->ptr[j][i] = (short) (y1val + yfrac * (y2val - y1val));

                    if (dvptr >= m_pMosaicVPyr && nC > 0)
                    {
                        y1val = suptr->ptr[y1][x1] +
                            (suptr->ptr[y1][x2] - suptr->ptr[y1][x1]) * xfrac;
                        y2val = suptr->ptr[y2][x1] +
                            (suptr->ptr[y2][x2] - suptr->ptr[y2][x1]) * xfrac;

                        duptr->ptr[j][i] = (short) (y1val + yfrac * (y2val - y1val));

                        y1val = svptr->ptr[y1][x1] +
                            (svptr->ptr[y1][x2] - svptr->ptr[y1][x1]) * xfrac;
                        y2val = svptr->ptr[y2][x1] +
                            (svptr->ptr[y2][x2] - svptr->ptr[y2][x1]) * xfrac;

                        dvptr->ptr[j][i] = (short) (y1val + yfrac * (y2val - y1val));
                    }
                }
#endif
                else
                {
                    clipToSegment(x1, sptr->width, BORDER);
                    clipToSegment(y1, sptr->height, BORDER);

                    dptr->ptr[j][i] = (short) (wt0 * dptr->ptr[j][i] + 0.5 +
                            wt1 * sptr->ptr[y1][x1] );
                    if (dvptr >= m_pMosaicVPyr && nC > 0)
                    {
                        dvptr->ptr[j][i] = (short) (wt0 * dvptr->ptr[j][i] +
                                0.5 + wt1 * svptr->ptr[y1][x1] );
                        duptr->ptr[j][i] = (short) (wt0 * duptr->ptr[j][i] +
                                0.5 + wt1 * suptr->ptr[y1][x1] );
                    }
                }
            }
        }
    }
}

void Blend::MosaicToFrame(double trs[3][3], double x, double y, double &wx, double &wy)
{
    double X, Y, z;
    if (m_wb.theta == 0.0)
    {
        X = x;
        Y = y;
    }
    else if (m_wb.horizontal)
    {
        double alpha = x * m_wb.direction / m_wb.width;
        double length = (y - alpha * m_wb.correction) * m_wb.direction + m_wb.radius;
        double deltaTheta = m_wb.theta * alpha;
        double sinTheta = sin(deltaTheta);
        double cosTheta = sqrt(1.0 - sinTheta * sinTheta) * m_wb.direction;
        X = length * sinTheta + m_wb.x;
        Y = length * cosTheta + m_wb.y;
    }
    else
    {
        double alpha = y * m_wb.direction / m_wb.width;
        double length = (x - alpha * m_wb.correction) * m_wb.direction + m_wb.radius;
        double deltaTheta = m_wb.theta * alpha;
        double sinTheta = sin(deltaTheta);
        double cosTheta = sqrt(1.0 - sinTheta * sinTheta) * m_wb.direction;
        Y = length * sinTheta + m_wb.y;
        X = length * cosTheta + m_wb.x;
    }
    z = ProjZ(trs, X, Y, 1.0);
    wx = ProjX(trs, X, Y, z, 1.0);
    wy = ProjY(trs, X, Y, z, 1.0);
}

void Blend::FrameToMosaic(double trs[3][3], double x, double y, double &wx, double &wy)
{
    // Project into the intermediate Mosaic coordinate system
    double z = ProjZ(trs, x, y, 1.0);
    double X = ProjX(trs, x, y, z, 1.0);
    double Y = ProjY(trs, x, y, z, 1.0);

    if (m_wb.theta == 0.0)
    {
        // No rotation, then this is all we need to do.
        wx = X;
        wy = Y;
    }
    else if (m_wb.horizontal)
    {
        double deltaX = X - m_wb.x;
        double deltaY = Y - m_wb.y;
        double length = sqrt(deltaX * deltaX + deltaY * deltaY);
        double deltaTheta = asin(deltaX / length);
        double alpha = deltaTheta / m_wb.theta;
        wx = alpha * m_wb.width * m_wb.direction;
        wy = (length - m_wb.radius) * m_wb.direction + alpha * m_wb.correction;
    }
    else
    {
        double deltaX = X - m_wb.x;
        double deltaY = Y - m_wb.y;
        double length = sqrt(deltaX * deltaX + deltaY * deltaY);
        double deltaTheta = asin(deltaY / length);
        double alpha = deltaTheta / m_wb.theta;
        wy = alpha * m_wb.width * m_wb.direction;
        wx = (length - m_wb.radius) * m_wb.direction + alpha * m_wb.correction;
    }
}



// Clip the region of interest as small as possible by using the Voronoi edges of
// the neighbors
void Blend::ClipBlendRect(CSite *csite, BlendRect &brect)
{
      SEdgeVector *ce;
      int ecnt;
      for (ce = csite->getNeighbor(), ecnt = csite->getNumNeighbors(); ecnt--; ce++)
      {
        // calculate the Voronoi bisector intersection
        const double epsilon = 1e-5;
        double dx = (m_AllSites[ce->second].getVCenter().x - m_AllSites[ce->first].getVCenter().x);
        double dy = (m_AllSites[ce->second].getVCenter().y - m_AllSites[ce->first].getVCenter().y);
        double xmid = m_AllSites[ce->first].getVCenter().x + dx/2.0;
        double ymid = m_AllSites[ce->first].getVCenter().y + dy/2.0;
        double inter;

        if (dx > epsilon)
        {
          // neighbor is on right
          if ((inter = m_wb.roundoffOverlap + xmid - dy * (((dy >= 0.0) ? brect.bot : brect.top) - ymid) / dx) < brect.rgt)
            brect.rgt = inter;
        }
        else if (dx < -epsilon)
        {
          // neighbor is on left
          if ((inter = -m_wb.roundoffOverlap + xmid - dy * (((dy >= 0.0) ? brect.bot : brect.top) - ymid) / dx) > brect.lft)
            brect.lft = inter;
        }
        if (dy > epsilon)
        {
          // neighbor is above
          if ((inter = m_wb.roundoffOverlap + ymid - dx * (((dx >= 0.0) ? brect.lft : brect.rgt) - xmid) / dy) < brect.top)
            brect.top = inter;
        }
        else if (dy < -epsilon)
        {
          // neighbor is below
          if ((inter = -m_wb.roundoffOverlap + ymid - dx * (((dx >= 0.0) ? brect.lft : brect.rgt) - xmid) / dy) > brect.bot)
            brect.bot = inter;
        }
      }
}

void Blend::FrameToMosaicRect(int width, int height, double trs[3][3], BlendRect &brect)
{
    // We need to walk the perimeter since the borders can be bent.
    brect.lft = brect.bot = 2e30;
    brect.rgt = brect.top = -2e30;
    double xpos, ypos;
    double lasty = height - 1.0;
    double lastx = width - 1.0;
    int i;

    for (i = width; i--;)
    {

        FrameToMosaic(trs, (double) i, 0.0, xpos, ypos);
        ClipRect(xpos, ypos, brect);
        FrameToMosaic(trs, (double) i, lasty, xpos, ypos);
        ClipRect(xpos, ypos, brect);
    }
    for (i = height; i--;)
    {
        FrameToMosaic(trs, 0.0, (double) i, xpos, ypos);
        ClipRect(xpos, ypos, brect);
        FrameToMosaic(trs, lastx, (double) i, xpos, ypos);
        ClipRect(xpos, ypos, brect);
    }
}

void Blend::SelectRelevantFrames(MosaicFrame **frames, int frames_size,
        MosaicFrame **relevant_frames, int &relevant_frames_size)
{
    MosaicFrame *first = frames[0];
    MosaicFrame *last = frames[frames_size-1];
    MosaicFrame *mb;

    double fxpos = first->trs[0][2], fypos = first->trs[1][2];

    double midX = last->width / 2.0;
    double midY = last->height / 2.0;
    double z = ProjZ(first->trs, midX, midY, 1.0);
    double firstX, firstY;
    double prevX = firstX = ProjX(first->trs, midX, midY, z, 1.0);
    double prevY = firstY = ProjY(first->trs, midX, midY, z, 1.0);

    relevant_frames[0] = first; // Add first frame by default
    relevant_frames_size = 1;

    for (int i = 0; i < frames_size - 1; i++)
    {
        mb = frames[i];
        double currX, currY;
        z = ProjZ(mb->trs, midX, midY, 1.0);
        currX = ProjX(mb->trs, midX, midY, z, 1.0);
        currY = ProjY(mb->trs, midX, midY, z, 1.0);
        double deltaX = currX - prevX;
        double deltaY = currY - prevY;
        double center2centerDist = sqrt(deltaY * deltaY + deltaX * deltaX);

        if (fabs(deltaX) > STRIP_SEPARATION_THRESHOLD_PXLS ||
                fabs(deltaY) > STRIP_SEPARATION_THRESHOLD_PXLS)
        {
            relevant_frames[relevant_frames_size] = mb;
            relevant_frames_size++;

            prevX = currX;
            prevY = currY;
        }
    }

    // Add last frame by default
    relevant_frames[relevant_frames_size] = last;
    relevant_frames_size++;
}

void Blend::ComputeBlendParameters(MosaicFrame **frames, int frames_size, int is360)
{
    // For FULL and PAN modes, we do not unwarp the mosaic into a rectangular coordinate system
    // and so we set the theta to 0 and return.
    if (m_wb.blendingType != BLEND_TYPE_CYLPAN && m_wb.blendingType != BLEND_TYPE_HORZ)
    {
        m_wb.theta = 0.0;
        return;
    }

    MosaicFrame *first = frames[0];
    MosaicFrame *last = frames[frames_size-1];
    MosaicFrame *mb;

    double lxpos = last->trs[0][2], lypos = last->trs[1][2];
    double fxpos = first->trs[0][2], fypos = first->trs[1][2];

    // Calculate warp to produce proper stitching.
    // get x, y displacement
    double midX = last->width / 2.0;
    double midY = last->height / 2.0;
    double z = ProjZ(first->trs, midX, midY, 1.0);
    double firstX, firstY;
    double prevX = firstX = ProjX(first->trs, midX, midY, z, 1.0);
    double prevY = firstY = ProjY(first->trs, midX, midY, z, 1.0);

    double arcLength, lastTheta;
    m_wb.theta = lastTheta = arcLength = 0.0;

    // Step through all the frames to compute the total arc-length of the cone
    // swept while capturing the mosaic (in the original conical coordinate system).
    for (int i = 0; i < frames_size; i++)
    {
        mb = frames[i];
        double currX, currY;
        z = ProjZ(mb->trs, midX, midY, 1.0);
        currX = ProjX(mb->trs, midX, midY, z, 1.0);
        currY = ProjY(mb->trs, midX, midY, z, 1.0);
        double deltaX = currX - prevX;
        double deltaY = currY - prevY;

        // The arcLength is computed by summing the lengths of the chords
        // connecting the pairwise projected image centers of the input image frames.
        arcLength += sqrt(deltaY * deltaY + deltaX * deltaX);

        if (!is360)
        {
            double thisTheta = asin(mb->trs[1][0]);
            m_wb.theta += thisTheta - lastTheta;
            lastTheta = thisTheta;
        }

        prevX = currX;
        prevY = currY;
    }

    // Stretch this to end at the proper alignment i.e. the width of the
    // rectangle is determined by the arcLength computed above and the cone
    // sector angle is determined using the rotation of the last frame.
    m_wb.width = arcLength;
    if (is360) m_wb.theta = asin(last->trs[1][0]);

    // If there is no rotation, we're done.
    if (m_wb.theta != 0.0)
    {
        double dx = prevX - firstX;
        double dy = prevY - firstY;

        // If the mosaic was captured by sweeping horizontally
        if (abs(lxpos - fxpos) > abs(lypos - fypos))
        {
            m_wb.horizontal = 1;
            // Calculate radius position to make ends exactly the same Y offset
            double radiusTheta = dx / cos(3.14159 / 2.0 - m_wb.theta);
            m_wb.radius = dy + radiusTheta * cos(m_wb.theta);
            if (m_wb.radius < 0.0) m_wb.radius = -m_wb.radius;
        }
        else
        {
            m_wb.horizontal = 0;
            // Calculate radius position to make ends exactly the same Y offset
            double radiusTheta = dy / cos(3.14159 / 2.0 - m_wb.theta);
            m_wb.radius = dx + radiusTheta * cos(m_wb.theta);
            if (m_wb.radius < 0.0) m_wb.radius = -m_wb.radius;
        }

        // Determine major direction
        if (m_wb.horizontal)
        {
            // Horizontal strip
            // m_wb.x,y record the origin of the rectangle coordinate system.
            if (is360) m_wb.x = firstX;
            else
            {
                if (lxpos - fxpos < 0)
                {
                    m_wb.x = firstX + midX;
                    z = ProjZ(last->trs, 0.0, midY, 1.0);
                    prevX = ProjX(last->trs, 0.0, midY, z, 1.0);
                    prevY = ProjY(last->trs, 0.0, midY, z, 1.0);
                }
                else
                {
                    m_wb.x = firstX - midX;
                    z = ProjZ(last->trs, last->width - 1.0, midY, 1.0);
                    prevX = ProjX(last->trs, last->width - 1.0, midY, z, 1.0);
                    prevY = ProjY(last->trs, last->width - 1.0, midY, z, 1.0);
                }
            }
            dy = prevY - firstY;
            if (dy < 0.0) m_wb.direction = 1.0;
            else m_wb.direction = -1.0;
            m_wb.y = firstY - m_wb.radius * m_wb.direction;
            if (dy * m_wb.theta > 0.0) m_wb.width = -m_wb.width;
        }
        else
        {
            // Vertical strip
            if (is360) m_wb.y = firstY;
            else
            {
                if (lypos - fypos < 0)
                {
                    m_wb.x = firstY + midY;
                    z = ProjZ(last->trs, midX, 0.0, 1.0);
                    prevX = ProjX(last->trs, midX, 0.0, z, 1.0);
                    prevY = ProjY(last->trs, midX, 0.0, z, 1.0);
                }
                else
                {
                    m_wb.x = firstX - midX;
                    z = ProjZ(last->trs, midX, last->height - 1.0, 1.0);
                    prevX = ProjX(last->trs, midX, last->height - 1.0, z, 1.0);
                    prevY = ProjY(last->trs, midX, last->height - 1.0, z, 1.0);
                }
            }
            dx = prevX - firstX;
            if (dx < 0.0) m_wb.direction = 1.0;
            else m_wb.direction = -1.0;
            m_wb.x = firstX - m_wb.radius * m_wb.direction;
            if (dx * m_wb.theta > 0.0) m_wb.width = -m_wb.width;
        }

        // Calculate the correct correction factor
        double deltaX = prevX - m_wb.x;
        double deltaY = prevY - m_wb.y;
        double length = sqrt(deltaX * deltaX + deltaY * deltaY);
        double deltaTheta = (m_wb.horizontal) ? deltaX : deltaY;
        deltaTheta = asin(deltaTheta / length);
        m_wb.correction = ((m_wb.radius - length) * m_wb.direction) /
            (deltaTheta / m_wb.theta);
    }
}
