Example #1
0
void RGBColorSystem::Data::Initialize()
{
   /*
    * Normalize luminance coefficients
    */
   double s = Y.Sum();
   if ( 1 + s == 1 )
      throw Error( "Invalid luminance coefficients in RGB working color space initialization." );
   Y /= s;

   /*
    * RGB -> XYZ transformation matrix M
    */
   M = SetupMatrix( x, y, Y );

   /*
    * CIE X and CIE Z normalization coefficients
    */
   mX = M11 + M12 + M13;
   mZ = M31 + M32 + M33;

   /*
    * XYZ -> RGB inverse matrix M_
    */
   M_ = InverseMatrix( M );

   /*
    * Inverse gamma
    */
   if ( 1 + gamma == 1 || gamma < 0 )
      throw Error( "Invalid gamma value in RGB working color space initialization." );
   gammaInv = 1/gamma;

   /*
    * Find normalization coefficients for CIE a, b, c channels
    *
    * The idea here is to maximize dynamic range usage for each channel
    * (coding efficiency) while ensuring that they will be constrained to the
    * nominal range [0,1].
    */

   sample minab = 100, maxab = -100, maxc = -100;

   int minabR = 0, minabG = 0, minabB = 0;
   int maxabR = 0, maxabG = 0, maxabB = 0;
   int maxcR = 0, maxcG = 0, maxcB = 0;

   for ( int ri = 0; ri < 10; ++ri )
   {
      sample R = sample( ri/9.0 );

      for ( int gi = 0; gi < 10; ++gi )
      {
         sample G = sample( gi/9.0 );

         for ( int bi = 0; bi < 10; ++bi )
         {
            sample B = sample( bi/9.0 );

            sample X, Y, Z;
            RGBToCIEXYZ( X, Y, Z, R, G, B );

            RGBColorSystem::XYZLab( X );
            RGBColorSystem::XYZLab( Y );
            RGBColorSystem::XYZLab( Z );

            sample a = 5*(X - Y);
            sample b = 2*(Y - Z);
            sample c = Sqrt( a*a + b*b );

            sample mn = Min( a, b );
            sample mx = Max( a, b );

            if ( mn < minab )
            {
               minab = mn;
               minabR = ri;
               minabG = gi;
               minabB = bi;
            }

            if ( mx > maxab )
            {
               maxab = mx;
               maxabR = ri;
               maxabG = gi;
               maxabB = bi;
            }

            if ( c > maxc )
            {
               maxc = c;
               maxcR = ri;
               maxcG = gi;
               maxcB = bi;
            }
         }
      }
   }

   sample R0, R1, G0, G1, B0, B1;

   R0 = Max( 0, minabR-1 )/9.0;
   R1 = Min( 9, minabR+1 )/9.0;

   G0 = Max( 0, minabG-1 )/9.0;
   G1 = Min( 9, minabG+1 )/9.0;

   B0 = Max( 0, minabB-1 )/9.0;
   B1 = Min( 9, minabB+1 )/9.0;

   for ( sample R = R0; R < R1; R += 0.01 )
      for ( sample G = G0; G < G1; G += 0.01 )
         for ( sample B = B0; B < B1; B += 0.01 )
         {
            sample X, Y, Z;
            RGBToCIEXYZ( X, Y, Z, R, G, B );

            RGBColorSystem::XYZLab( X );
            RGBColorSystem::XYZLab( Y );
            RGBColorSystem::XYZLab( Z );

            sample mn = Min( 5*(X - Y), 2*(Y - Z) );
            if ( mn < minab )
               minab = mn;
         }

   R0 = Max( 0, maxabR-1 )/9.0;
   R1 = Min( 9, maxabR+1 )/9.0;

   G0 = Max( 0, maxabG-1 )/9.0;
   G1 = Min( 9, maxabG+1 )/9.0;

   B0 = Max( 0, maxabB-1 )/9.0;
   B1 = Min( 9, maxabB+1 )/9.0;

   for ( sample R = R0; R < R1; R += 0.01 )
      for ( sample G = G0; G < G1; G += 0.01 )
         for ( sample B = B0; B < B1; B += 0.01 )
         {
            sample X, Y, Z;
            RGBToCIEXYZ( X, Y, Z, R, G, B );

            RGBColorSystem::XYZLab( X );
            RGBColorSystem::XYZLab( Y );
            RGBColorSystem::XYZLab( Z );

            sample mx = Max( 5*(X - Y), 2*(Y - Z) );
            if ( mx > maxab )
               maxab = mx;
         }

   R0 = Max( 0, maxcR-1 )/9.0;
   R1 = Min( 9, maxcR+1 )/9.0;

   G0 = Max( 0, maxcG-1 )/9.0;
   G1 = Min( 9, maxcG+1 )/9.0;

   B0 = Max( 0, maxcB-1 )/9.0;
   B1 = Min( 9, maxcB+1 )/9.0;

   for ( sample R = R0; R < R1; R += 0.01 )
      for ( sample G = G0; G < G1; G += 0.01 )
         for ( sample B = B0; B < B1; B += 0.01 )
         {
            sample X, Y, Z;
            RGBToCIEXYZ( X, Y, Z, R, G, B );

            RGBColorSystem::XYZLab( X );
            RGBColorSystem::XYZLab( Y );
            RGBColorSystem::XYZLab( Z );

            sample a = 5*(X - Y);
            sample b = 2*(Y - Z);
            sample c = Sqrt( a*a + b*b );

            if ( c > maxc )
               maxc = c;
         }

   abOffset = -minab + 0.05;
   abDelta  =  maxab - minab + 0.1;
   cDelta   =  maxc + 0.05;
}
Example #2
0
  Matrix<F>& G )
{
    DEBUG_CSE
    const Int nU = U.Width();
    const Int n = A.Height();
    DEBUG_ONLY(
      if( nU >= n )            
          LogicError("V is too wide for the panel factorization");
      if( U.Height() != A.Height() )
          LogicError("U must be the same height as A");
      if( V.Height() != A.Height() )
          LogicError("V must be the same height as A");
      if( V.Width() != nU )
          LogicError("V must be the same width as U");
    )
    const Int phaseHeight = Max(nU,0);
    phase.Resize( phaseHeight, 1 );

    Zeros( U, n, nU );
    Zeros( V, n, nU );
    Zeros( G, nU, nU );

    Matrix<F> y10;

    for( Int k=0; k<nU; ++k )
    {
        const Range<Int> ind0( 0,   k   ),
                         ind1( k,   k+1 ),
                         ind2( k+1, n   );

        auto a12 = A( ind1, ind2    );
Example #3
0
/* contains negative values */
int zbeshv(double *xr, double *xi, int *nx,
           double *alpha, int *na, int *kode, int *k, double
           *yr, double *yi, double *wr, double *wi, int *ierr)
{
    double eps = C2F(dlamch)("p", strlen("p"));
    int iOne = 1;
    int i = 0, j = 0, nz = 0;

    *ierr = 0;
    if (*na < 0)
    {
        /* element wise case x and alpha are supposed to have the same size */
        for (i = 1; i <= *nx; ++i)
        {
            int ier = 0;
            zbeshg(&xr[i - 1], &xi[i - 1], &alpha[i - 1], kode, k, &iOne, &yr[i - 1],
                   &yi[i - 1], &nz, &wr[1], &wi[0], &ier);
            *ierr = Max(*ierr, ier);
        }
    }
    else if (*na == 1)
    {
        for (i = 1; i <= *nx; ++i)
        {
            int ier = 0;
            zbeshg(&xr[i - 1], &xi[i - 1], &alpha[0], kode, k, &iOne, &yr[i - 1],
                   &yi[i - 1], &nz, &wr[0], &wi[0], &ier);
            *ierr = Max(*ierr, ier);
        }
    }
    else
    {
        /* compute besselh(x(i),y(j)), i=1,nx,j=1,na */
        double dTmp = 0;
        int n = 0;
        int  l = 1;
L5:
        n = 0;
L10:
        ++n;
        j = l + n;
        if (j <= *na && (dTmp = alpha[j] + 1 - alpha[j - 1], fabs(dTmp)) <= eps)
        {
            goto L10;
        }
        for (i = 1; i <= *nx; ++i)
        {
            int ier = 0;
            zbeshg(&xr[i - 1], &xi[i - 1], &alpha[l - 1], kode, k, &n, &wr[0], &wi[0],
                   &nz, &wr[*na], &wi[*na], &ier);

            *ierr = Max(*ierr, ier);

            C2F(dcopy)(&n, &wr[0], &iOne, &yr[(i + (l - 1) * *nx) - 1], nx);

            C2F(dcopy)(&n, &wi[0], &iOne, &yi[(i + (l - 1) * *nx) - 1], nx);
        }

        l = j;

        if (l <= *na)
        {
            goto L5;
        }
    }
    return 0;
}
Example #4
0
/*
 * Receive a message from a shared message queue.
 *
 * We set *nbytes to the message length and *data to point to the message
 * payload.  If the entire message exists in the queue as a single,
 * contiguous chunk, *data will point directly into shared memory; otherwise,
 * it will point to a temporary buffer.  This mostly avoids data copying in
 * the hoped-for case where messages are short compared to the buffer size,
 * while still allowing longer messages.  In either case, the return value
 * remains valid until the next receive operation is perfomed on the queue.
 *
 * When nowait = false, we'll wait on our process latch when the ring buffer
 * is empty and we have not yet received a full message.  The sender will
 * set our process latch after more data has been written, and we'll resume
 * processing.  Each call will therefore return a complete message
 * (unless the sender detaches the queue).
 *
 * When nowait = true, we do not manipulate the state of the process latch;
 * instead, whenever the buffer is empty and we need to read from it, we
 * return SHM_MQ_WOULD_BLOCK.  In this case, the caller should call this
 * function again after the process latch has been set.
 */
shm_mq_result
shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
{
	shm_mq	   *mq = mqh->mqh_queue;
	shm_mq_result res;
	Size		rb = 0;
	Size		nbytes;
	void	   *rawdata;

	Assert(mq->mq_receiver == MyProc);

	/* We can't receive data until the sender has attached. */
	if (!mqh->mqh_counterparty_attached)
	{
		if (nowait)
		{
			if (shm_mq_get_sender(mq) == NULL)
				return SHM_MQ_WOULD_BLOCK;
		}
		else if (!shm_mq_wait_internal(mq, &mq->mq_sender, mqh->mqh_handle)
				 && shm_mq_get_sender(mq) == NULL)
		{
			mq->mq_detached = true;
			return SHM_MQ_DETACHED;
		}
		mqh->mqh_counterparty_attached = true;
	}

	/* Consume any zero-copy data from previous receive operation. */
	if (mqh->mqh_consume_pending > 0)
	{
		shm_mq_inc_bytes_read(mq, mqh->mqh_consume_pending);
		mqh->mqh_consume_pending = 0;
	}

	/* Try to read, or finish reading, the length word from the buffer. */
	while (!mqh->mqh_length_word_complete)
	{
		/* Try to receive the message length word. */
		Assert(mqh->mqh_partial_bytes < sizeof(Size));
		res = shm_mq_receive_bytes(mq, sizeof(Size) - mqh->mqh_partial_bytes,
								   nowait, &rb, &rawdata);
		if (res != SHM_MQ_SUCCESS)
			return res;

		/*
		 * Hopefully, we'll receive the entire message length word at once.
		 * But if sizeof(Size) > MAXIMUM_ALIGNOF, then it might be split over
		 * multiple reads.
		 */
		if (mqh->mqh_partial_bytes == 0 && rb >= sizeof(Size))
		{
			Size		needed;

			nbytes = *(Size *) rawdata;

			/* If we've already got the whole message, we're done. */
			needed = MAXALIGN(sizeof(Size)) + MAXALIGN(nbytes);
			if (rb >= needed)
			{
				/*
				 * Technically, we could consume the message length
				 * information at this point, but the extra write to shared
				 * memory wouldn't be free and in most cases we would reap no
				 * benefit.
				 */
				mqh->mqh_consume_pending = needed;
				*nbytesp = nbytes;
				*datap = ((char *) rawdata) + MAXALIGN(sizeof(Size));
				return SHM_MQ_SUCCESS;
			}

			/*
			 * We don't have the whole message, but we at least have the whole
			 * length word.
			 */
			mqh->mqh_expected_bytes = nbytes;
			mqh->mqh_length_word_complete = true;
			shm_mq_inc_bytes_read(mq, MAXALIGN(sizeof(Size)));
			rb -= MAXALIGN(sizeof(Size));
		}
		else
		{
			Size		lengthbytes;

			/* Can't be split unless bigger than required alignment. */
			Assert(sizeof(Size) > MAXIMUM_ALIGNOF);

			/* Message word is split; need buffer to reassemble. */
			if (mqh->mqh_buffer == NULL)
			{
				mqh->mqh_buffer = MemoryContextAlloc(mqh->mqh_context,
													 MQH_INITIAL_BUFSIZE);
				mqh->mqh_buflen = MQH_INITIAL_BUFSIZE;
			}
			Assert(mqh->mqh_buflen >= sizeof(Size));

			/* Copy and consume partial length word. */
			if (mqh->mqh_partial_bytes + rb > sizeof(Size))
				lengthbytes = sizeof(Size) - mqh->mqh_partial_bytes;
			else
				lengthbytes = rb;
			memcpy(&mqh->mqh_buffer[mqh->mqh_partial_bytes], rawdata,
				   lengthbytes);
			mqh->mqh_partial_bytes += lengthbytes;
			shm_mq_inc_bytes_read(mq, MAXALIGN(lengthbytes));
			rb -= lengthbytes;

			/* If we now have the whole word, we're ready to read payload. */
			if (mqh->mqh_partial_bytes >= sizeof(Size))
			{
				Assert(mqh->mqh_partial_bytes == sizeof(Size));
				mqh->mqh_expected_bytes = *(Size *) mqh->mqh_buffer;
				mqh->mqh_length_word_complete = true;
				mqh->mqh_partial_bytes = 0;
			}
		}
	}
	nbytes = mqh->mqh_expected_bytes;

	if (mqh->mqh_partial_bytes == 0)
	{
		/*
		 * Try to obtain the whole message in a single chunk.  If this works,
		 * we need not copy the data and can return a pointer directly into
		 * shared memory.
		 */
		res = shm_mq_receive_bytes(mq, nbytes, nowait, &rb, &rawdata);
		if (res != SHM_MQ_SUCCESS)
			return res;
		if (rb >= nbytes)
		{
			mqh->mqh_length_word_complete = false;
			mqh->mqh_consume_pending = MAXALIGN(nbytes);
			*nbytesp = nbytes;
			*datap = rawdata;
			return SHM_MQ_SUCCESS;
		}

		/*
		 * The message has wrapped the buffer.  We'll need to copy it in order
		 * to return it to the client in one chunk.  First, make sure we have
		 * a large enough buffer available.
		 */
		if (mqh->mqh_buflen < nbytes)
		{
			Size		newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);

			while (newbuflen < nbytes)
				newbuflen *= 2;

			if (mqh->mqh_buffer != NULL)
			{
				pfree(mqh->mqh_buffer);
				mqh->mqh_buffer = NULL;
				mqh->mqh_buflen = 0;
			}
			mqh->mqh_buffer = MemoryContextAlloc(mqh->mqh_context, newbuflen);
			mqh->mqh_buflen = newbuflen;
		}
	}

	/* Loop until we've copied the entire message. */
	for (;;)
	{
		Size		still_needed;

		/* Copy as much as we can. */
		Assert(mqh->mqh_partial_bytes + rb <= nbytes);
		memcpy(&mqh->mqh_buffer[mqh->mqh_partial_bytes], rawdata, rb);
		mqh->mqh_partial_bytes += rb;

		/*
		 * Update count of bytes read, with alignment padding.  Note that this
		 * will never actually insert any padding except at the end of a
		 * message, because the buffer size is a multiple of MAXIMUM_ALIGNOF,
		 * and each read and write is as well.
		 */
		Assert(mqh->mqh_partial_bytes == nbytes || rb == MAXALIGN(rb));
		shm_mq_inc_bytes_read(mq, MAXALIGN(rb));

		/* If we got all the data, exit the loop. */
		if (mqh->mqh_partial_bytes >= nbytes)
			break;

		/* Wait for some more data. */
		still_needed = nbytes - mqh->mqh_partial_bytes;
		res = shm_mq_receive_bytes(mq, still_needed, nowait, &rb, &rawdata);
		if (res != SHM_MQ_SUCCESS)
			return res;
		if (rb > still_needed)
			rb = still_needed;
	}

	/* Return the complete message, and reset for next message. */
	*nbytesp = nbytes;
	*datap = mqh->mqh_buffer;
	mqh->mqh_length_word_complete = false;
	mqh->mqh_partial_bytes = 0;
	return SHM_MQ_SUCCESS;
}
Example #5
0
void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
{
    FontFace* face = font_ ? font_->GetFace(fontSize_) : (FontFace*)0;
    if (!face)
    {
        hovering_ = false;
        return;
    }

    // If face has changed or char locations are not valid anymore, update before rendering
    if (charLocationsDirty_ || !fontFace_ || face != fontFace_)
        UpdateCharLocations();
    // If face uses mutable glyphs mechanism, reacquire glyphs before rendering to make sure they are in the texture
    else if (face->HasMutableGlyphs())
    {
        for (unsigned i = 0; i < printText_.Size(); ++i)
            face->GetGlyph(printText_[i]);
    }

    // Hovering and/or whole selection batch
    if ((hovering_ && hoverColor_.a_ > 0.0) || (selected_ && selectionColor_.a_ > 0.0f))
    {
        bool both = hovering_ && selected_ && hoverColor_.a_ > 0.0 && selectionColor_.a_ > 0.0f;
        UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
        batch.SetColor(both ? selectionColor_.Lerp(hoverColor_, 0.5f) :
            (selected_ && selectionColor_.a_ > 0.0f ? selectionColor_ : hoverColor_));
        batch.AddQuad(0, 0, GetWidth(), GetHeight(), 0, 0);
        UIBatch::AddOrMerge(batch, batches);
    }

    // Partial selection batch
    if (!selected_ && selectionLength_ && charLocations_.Size() >= selectionStart_ + selectionLength_ && selectionColor_.a_ > 0.0f)
    {
        UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
        batch.SetColor(selectionColor_);

        IntVector2 currentStart = charLocations_[selectionStart_].position_;
        IntVector2 currentEnd = currentStart;
        for (unsigned i = selectionStart_; i < selectionStart_ + selectionLength_; ++i)
        {
            // Check if row changes, and start a new quad in that case
            if (charLocations_[i].size_ != IntVector2::ZERO)
            {
                if (charLocations_[i].position_.y_ != currentStart.y_)
                {
                    batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_,
                        currentEnd.y_ - currentStart.y_, 0, 0);
                    currentStart = charLocations_[i].position_;
                    currentEnd = currentStart + charLocations_[i].size_;
                }
                else
                {
                    currentEnd.x_ += charLocations_[i].size_.x_;
                    currentEnd.y_ = Max(currentStart.y_ + charLocations_[i].size_.y_, currentEnd.y_);
                }
            }
        }
        if (currentEnd != currentStart)
        {
            batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_, currentEnd.y_ - currentStart.y_, 0, 0);
        }

        UIBatch::AddOrMerge(batch, batches);
    }

    // Text batch
    TextEffect textEffect = font_->IsSDFFont() ? TE_NONE : textEffect_;
    const Vector<SharedPtr<Texture2D> >& textures = face->GetTextures();
    for (unsigned n = 0; n < textures.Size() && n < pageGlyphLocations_.Size(); ++n)
    {
        // One batch per texture/page
        UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, textures[n], &vertexData);

        const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations_[n];

        switch (textEffect)
        {
        case TE_NONE:
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_SHADOW:
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_STROKE:
            ConstructBatch(pageBatch, pageGlyphLocation, -1, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, -1, 0, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 0, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, -1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;
        }

        UIBatch::AddOrMerge(pageBatch, batches);
    }

    // Reset hovering for next frame
    hovering_ = false;
}
Example #6
0
bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
{
    if (!image)
    {
        URHO3D_LOGERROR("Null image, can not set data");
        return false;
    }
    if (!layers_)
    {
        URHO3D_LOGERROR("Number of layers in the array must be set first");
        return false;
    }
    if (layer >= layers_)
    {
        URHO3D_LOGERROR("Illegal layer for setting data");
        return false;
    }

    // Use a shared ptr for managing the temporary mip images created during this function
    SharedPtr<Image> mipImage;
    unsigned memoryUse = 0;
    int quality = QUALITY_HIGH;
    Renderer* renderer = GetSubsystem<Renderer>();
    if (renderer)
        quality = renderer->GetTextureQuality();

    if (!image->IsCompressed())
    {
        // Convert unsuitable formats to RGBA
        unsigned components = image->GetComponents();
        if (Graphics::GetGL3Support() && ((components == 1 && !useAlpha) || components == 2))
        {
            mipImage = image->ConvertToRGBA(); image = mipImage;
            if (!image)
                return false;
            components = image->GetComponents();
        }

        unsigned char* levelData = image->GetData();
        int levelWidth = image->GetWidth();
        int levelHeight = image->GetHeight();
        unsigned format = 0;

        // Discard unnecessary mip levels
        for (unsigned i = 0; i < mipsToSkip_[quality]; ++i)
        {
            mipImage = image->GetNextLevel(); image = mipImage;
            levelData = image->GetData();
            levelWidth = image->GetWidth();
            levelHeight = image->GetHeight();
        }

        switch (components)
        {
        case 1:
            format = useAlpha ? Graphics::GetAlphaFormat() : Graphics::GetLuminanceFormat();
            break;

        case 2:
            format = Graphics::GetLuminanceAlphaFormat();
            break;

        case 3:
            format = Graphics::GetRGBFormat();
            break;

        case 4:
            format = Graphics::GetRGBAFormat();
            break;

        default:
            assert(false);  // Should not reach here
            break;
        }

        // Create the texture array when layer 0 is being loaded, check that rest of the layers are same size & format
        if (!layer)
        {
            // If image was previously compressed, reset number of requested levels to avoid error if level count is too high for new size
            if (IsCompressed() && requestedLevels_ > 1)
                requestedLevels_ = 0;
            // Create the texture array (the number of layers must have been already set)
            SetSize(0, levelWidth, levelHeight, format);
        }
        else
        {
            if (!object_.name_)
            {
                URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                return false;
            }
            if (levelWidth != width_ || levelHeight != height_ || format != format_)
            {
                URHO3D_LOGERROR("Texture array layer does not match size or format of layer 0");
                return false;
            }
        }

        for (unsigned i = 0; i < levels_; ++i)
        {
            SetData(layer, i, 0, 0, levelWidth, levelHeight, levelData);
            memoryUse += levelWidth * levelHeight * components;

            if (i < levels_ - 1)
            {
                mipImage = image->GetNextLevel(); image = mipImage;
                levelData = image->GetData();
                levelWidth = image->GetWidth();
                levelHeight = image->GetHeight();
            }
        }
    }
    else
    {
        int width = image->GetWidth();
        int height = image->GetHeight();
        unsigned levels = image->GetNumCompressedLevels();
        unsigned format = graphics_->GetFormat(image->GetCompressedFormat());
        bool needDecompress = false;

        if (!format)
        {
            format = Graphics::GetRGBAFormat();
            needDecompress = true;
        }

        unsigned mipsToSkip = mipsToSkip_[quality];
        if (mipsToSkip >= levels)
            mipsToSkip = levels - 1;
        while (mipsToSkip && (width / (1 << mipsToSkip) < 4 || height / (1 << mipsToSkip) < 4))
            --mipsToSkip;
        width /= (1 << mipsToSkip);
        height /= (1 << mipsToSkip);

        // Create the texture array when layer 0 is being loaded, assume rest of the layers are same size & format
        if (!layer)
        {
            SetNumLevels(Max((levels - mipsToSkip), 1U));
            SetSize(0, width, height, format);
        }
        else
        {
            if (!object_.name_)
            {
                URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                return false;
            }
            if (width != width_ || height != height_ || format != format_)
            {
                URHO3D_LOGERROR("Texture array layer does not match size or format of layer 0");
                return false;
            }
        }

        for (unsigned i = 0; i < levels_ && i < levels - mipsToSkip; ++i)
        {
            CompressedLevel level = image->GetCompressedLevel(i + mipsToSkip);
            if (!needDecompress)
            {
                SetData(layer, i, 0, 0, level.width_, level.height_, level.data_);
                memoryUse += level.rows_ * level.rowSize_;
            }
            else
            {
                unsigned char* rgbaData = new unsigned char[level.width_ * level.height_ * 4];
                level.Decompress(rgbaData);
                SetData(layer, i, 0, 0, level.width_, level.height_, rgbaData);
                memoryUse += level.width_ * level.height_ * 4;
                delete[] rgbaData;
            }
        }
    }

    layerMemoryUse_[layer] = memoryUse;
    unsigned totalMemoryUse = sizeof(Texture2DArray) + layerMemoryUse_.Capacity() * sizeof(unsigned);
    for (unsigned i = 0; i < layers_; ++i)
        totalMemoryUse += layerMemoryUse_[i];
    SetMemoryUse(totalMemoryUse);

    return true;
}
Example #7
0
Int ADMM
( const Matrix<Real>& A, 
  const Matrix<Real>& b, const Matrix<Real>& c, 
        Matrix<Real>& z,
  const ADMMCtrl<Real>& ctrl )
{
    DEBUG_ONLY(CSE cse("lp::direct::ADMM"))
    
    // Cache a custom partially-pivoted LU factorization of 
    //    |  rho*I   A^H | = | B11  B12 |
    //    |  A       0   |   | B21  B22 |
    // by (justifiably) avoiding pivoting in the first n steps of
    // the factorization, so that
    //    [I,rho*I] = lu(rho*I).
    // The factorization would then proceed with 
    //    B21 := B21 U11^{-1} = A (rho*I)^{-1} = A/rho
    //    B12 := L11^{-1} B12 = I A^H = A^H.
    // The Schur complement would then be
    //    B22 := B22 - B21 B12 = 0 - (A*A^H)/rho.
    // We then factor said matrix with LU with partial pivoting and
    // swap the necessary rows of B21 in order to implicitly commute
    // the row pivots with the Gauss transforms in the manner standard
    // for GEPP. Unless A A' is singular, pivoting should not be needed,
    // as Cholesky factorization of the negative matrix should be valid.
    //
    // The result is the factorization
    //   | I 0   | | rho*I A^H | = | I   0   | | rho*I U12 |,
    //   | 0 P22 | | A     0   |   | L21 L22 | | 0     U22 |
    // where [L22,U22] are stored within B22.
    Matrix<Real> U12, L21, B22, bPiv;
    Adjoint( A, U12 );
    L21 = A; 
    L21 *= 1/ctrl.rho;
    Herk( LOWER, NORMAL, -1/ctrl.rho, A, B22 );
    MakeHermitian( LOWER, B22 );
    // TODO: Replace with sparse-direct Cholesky version?
    Matrix<Int> rowPiv2;
    LU( B22, rowPiv2 );
    ApplyRowPivots( L21, rowPiv2 );
    bPiv = b;
    ApplyRowPivots( bPiv, rowPiv2 );

    // Possibly form the inverse of L22 U22
    Matrix<Real> X22;
    if( ctrl.inv )
    {
        X22 = B22;
        MakeTrapezoidal( LOWER, X22 );
        FillDiagonal( X22, Real(1) );
        TriangularInverse( LOWER, UNIT, X22 );
        Trsm( LEFT, UPPER, NORMAL, NON_UNIT, Real(1), B22, X22 );
    }

    Int numIter=0;
    const Int m = A.Height();
    const Int n = A.Width();
    Matrix<Real> g, xTmp, y, t;
    Zeros( g, m+n, 1 );
    PartitionDown( g, xTmp, y, n );
    Matrix<Real> x, u, zOld, xHat;
    Zeros( z, n, 1 );
    Zeros( u, n, 1 );
    Zeros( t, n, 1 );
    while( numIter < ctrl.maxIter )
    {
        zOld = z;

        // Find x from
        //  | rho*I  A^H | | x | = | rho*(z-u)-c | 
        //  | A      0   | | y |   | b           |
        // via our cached custom factorization:
        // 
        // |x| = inv(U) inv(L) P' |rho*(z-u)-c|
        // |y|                    |b          |
        //     = |rho*I U12|^{-1} |I   0  | |I 0   | |rho*(z-u)-c|
        //     = |0     U22|      |L21 L22| |0 P22'| |b          |
        //     = "                        " |rho*(z-u)-c|
        //                                  | P22' b    |
        xTmp = z;
        xTmp -= u;
        xTmp *= ctrl.rho;
        xTmp -= c;
        y = bPiv;
        Gemv( NORMAL, Real(-1), L21, xTmp, Real(1), y );
        if( ctrl.inv )
        {
            Gemv( NORMAL, Real(1), X22, y, t );
            y = t;
        }
        else
        {
            Trsv( LOWER, NORMAL, UNIT, B22, y );
            Trsv( UPPER, NORMAL, NON_UNIT, B22, y );
        }
        Gemv( NORMAL, Real(-1), U12, y, Real(1), xTmp );
        xTmp *= 1/ctrl.rho;

        // xHat := alpha*x + (1-alpha)*zOld
        xHat = xTmp;
        xHat *= ctrl.alpha;
        Axpy( 1-ctrl.alpha, zOld, xHat );

        // z := pos(xHat+u)
        z = xHat;
        z += u;
        LowerClip( z, Real(0) );

        // u := u + (xHat-z)
        u += xHat;
        u -= z;

        const Real objective = Dot( c, xTmp );

        // rNorm := || x - z ||_2
        t = xTmp;
        t -= z;
        const Real rNorm = FrobeniusNorm( t );
        // sNorm := |rho| || z - zOld ||_2
        t = z;
        t -= zOld;
        const Real sNorm = Abs(ctrl.rho)*FrobeniusNorm( t );

        const Real epsPri = Sqrt(Real(n))*ctrl.absTol +
            ctrl.relTol*Max(FrobeniusNorm(xTmp),FrobeniusNorm(z));
        const Real epsDual = Sqrt(Real(n))*ctrl.absTol +
            ctrl.relTol*Abs(ctrl.rho)*FrobeniusNorm(u);

        if( ctrl.print )
        {
            t = xTmp;
            LowerClip( t, Real(0) );
            t -= xTmp;
            const Real clipDist = FrobeniusNorm( t );
            cout << numIter << ": "
              << "||x-z||_2=" << rNorm << ", "
              << "epsPri=" << epsPri << ", "
              << "|rho| ||z-zOld||_2=" << sNorm << ", "
              << "epsDual=" << epsDual << ", "
              << "||x-Pos(x)||_2=" << clipDist << ", "
              << "c'x=" << objective << endl;
        }
        if( rNorm < epsPri && sNorm < epsDual )
            break;
        ++numIter;
    }
    if( ctrl.maxIter == numIter )
        cout << "ADMM failed to converge" << endl;
    x = xTmp;
    return numIter;
}
Example #8
0
void ETHParticleManager::SetSoundVolume(const float volume)
{
	m_entityVolume = Min(Max(volume, 0.0f), 1.0f);
}
Example #9
0
bool ETHParticleManager::UpdateParticleSystem(
	const Vector2& v2Pos,
	const Vector3& v3Pos,
	const float angle,
	const unsigned long lastFrameElapsedTime)
{
	bool anythingDrawn = false;
	const unsigned long cappedLastFrameElapsedTime = Min(lastFrameElapsedTime, static_cast<unsigned long>(250));
	const float frameSpeed = static_cast<float>((static_cast<double>(cappedLastFrameElapsedTime) / 1000.0) * 60.0);

	Matrix4x4 rot = RotateZ(DegreeToRadian(angle));
	m_nActiveParticles = 0;
	for (int t = 0; t < m_system.nParticles; t++)
	{
		PARTICLE& particle = m_particles[t];

		if (m_system.repeat > 0)
			if (particle.repeat >= m_system.repeat)
				continue;

		// check how many particles are active
		if (particle.size > 0.0f && particle.released)
		{
			if (!Killed() || (Killed() && particle.elapsed < particle.lifeTime))
				m_nActiveParticles++;
		}

		anythingDrawn = true;

		particle.elapsed += lastFrameElapsedTime;

		if (!particle.released)
		{
			// if we shouldn't release all particles at the same time, check if it's time to release this particle
			const float releaseTime = 
				((m_system.lifeTime + m_system.randomizeLifeTime) * (static_cast<float>(particle.id) / static_cast<float>(m_system.nParticles)));

			if (particle.elapsed > releaseTime || m_system.allAtOnce)
			{
				particle.elapsed = 0.0f;
				particle.released = true;
				PositionParticle(t, v2Pos, angle, rot, v3Pos);
			}
		}

		if (particle.released)
		{
			particle.dir += (m_system.gravityVector * frameSpeed);
			particle.pos += (particle.dir * frameSpeed);
			particle.angle += (particle.angleDir * frameSpeed);
			particle.size  += (m_system.growth * frameSpeed);
			const float w = particle.elapsed / particle.lifeTime;
			particle.color = m_system.color0 + (m_system.color1 - m_system.color0) * w;

			// update particle animation if there is any
			if (m_system.spriteCut.x > 1 || m_system.spriteCut.y > 1)
			{
				if (m_system.animationMode == ETHParticleSystem::PLAY_ANIMATION)
				{
					particle.currentFrame = static_cast<unsigned int>(
						Min(static_cast<int>(static_cast<float>(m_system.GetNumFrames()) * w),
							m_system.GetNumFrames() - 1));
				}
			}

			particle.size = Min(particle.size, m_system.maxSize);
			particle.size = Max(particle.size, m_system.minSize);

			if (particle.elapsed > particle.lifeTime)
			{
				particle.repeat++;
				if (!Killed())
					ResetParticle(t, v2Pos, v3Pos, angle, rot);
			}
		}
	}
	m_finished = !anythingDrawn;

	// manages the sound
	HandleSoundPlayback(v2Pos, frameSpeed);

	return true;
}
Example #10
0
bool ParticleEffect2D::BeginLoad(Deserializer& source)
{
    if (GetName().Empty())
        SetName(source.GetName());

    loadSpriteName_.Clear();

    XMLFile xmlFile(context_);
    if (!xmlFile.Load(source))
        return false;

    XMLElement rootElem = xmlFile.GetRoot("particleEmitterConfig");
    if (!rootElem)
        return false;

    String texture = rootElem.GetChild("texture").GetAttribute("name");
    loadSpriteName_ = GetParentPath(GetName()) + texture;
    // If async loading, request the sprite beforehand
    if (GetAsyncLoadState() == ASYNC_LOADING)
        GetSubsystem<ResourceCache>()->BackgroundLoadResource<Sprite2D>(loadSpriteName_, true, this);

    sourcePositionVariance_ = ReadVector2(rootElem, "sourcePositionVariance");

    speed_ = ReadFloat(rootElem, "speed");
    speedVariance_ = ReadFloat(rootElem, "speedVariance");

    particleLifeSpan_ = Max(0.01f, ReadFloat(rootElem, "particleLifeSpan"));
    particleLifespanVariance_ = ReadFloat(rootElem, "particleLifespanVariance");

    angle_ = ReadFloat(rootElem, "angle");
    angleVariance_ = ReadFloat(rootElem, "angleVariance");

    gravity_ = ReadVector2(rootElem, "gravity");

    radialAcceleration_ = ReadFloat(rootElem, "radialAcceleration");
    tangentialAcceleration_ = ReadFloat(rootElem, "tangentialAcceleration");

    radialAccelVariance_ = ReadFloat(rootElem, "radialAccelVariance");
    tangentialAccelVariance_ = ReadFloat(rootElem, "tangentialAccelVariance");

    startColor_ = ReadColor(rootElem, "startColor");
    startColorVariance_ = ReadColor(rootElem, "startColorVariance");

    finishColor_ = ReadColor(rootElem, "finishColor");
    finishColorVariance_ = ReadColor(rootElem, "finishColorVariance");

    maxParticles_ = ReadInt(rootElem, "maxParticles");

    startParticleSize_ = ReadFloat(rootElem, "startParticleSize");
    startParticleSizeVariance_ = ReadFloat(rootElem, "startParticleSizeVariance");

    finishParticleSize_ = ReadFloat(rootElem, "finishParticleSize");
    // Typo in pex file
    finishParticleSizeVariance_ = ReadFloat(rootElem, "FinishParticleSizeVariance");

    duration_ = M_INFINITY;
    if (rootElem.HasChild("duration"))
    {
        float duration = ReadFloat(rootElem, "duration");
        if (duration > 0.0f)
            duration_ = duration;
    }


    emitterType_ = (EmitterType2D)ReadInt(rootElem, "emitterType");

    maxRadius_ = ReadFloat(rootElem, "maxRadius");
    maxRadiusVariance_ = ReadFloat(rootElem, "maxRadiusVariance");
    minRadius_ = ReadFloat(rootElem, "minRadius");
    minRadiusVariance_ = ReadFloat(rootElem, "minRadiusVariance");

    rotatePerSecond_ = ReadFloat(rootElem, "rotatePerSecond");
    rotatePerSecondVariance_ = ReadFloat(rootElem, "rotatePerSecondVariance");

    int blendFuncSource = ReadInt(rootElem, "blendFuncSource");
    int blendFuncDestination = ReadInt(rootElem, "blendFuncDestination");
    blendMode_ = BLEND_ALPHA;
    for (int i = 0; i < MAX_BLENDMODES; ++i)
    {
        if (blendFuncSource == srcBlendFuncs[i] && blendFuncDestination == destBlendFuncs[i])
        {
            blendMode_ = (BlendMode)i;
            break;
        }
    }

    rotationStart_ = ReadFloat(rootElem, "rotationStart");
    rotationStartVariance_ = ReadFloat(rootElem, "rotationStartVariance");

    rotationEnd_ = ReadFloat(rootElem, "rotationEnd");
    rotationEndVariance_ = ReadFloat(rootElem, "rotationEndVariance");

    // Note: not accurate
    SetMemoryUse(source.GetSize());
    return true;
}
Example #11
0
/** Show the menu associated with a task list item. */
void ShowClientList(TaskBarType *bar, TaskEntry *tp)
{
   Menu *menu;
   MenuItem *item;
   ClientEntry *cp;

   const ScreenType *sp;
   int x, y;
   Window w;

   if(settings.groupTasks) {

      menu = CreateMenu();

      item = CreateMenuItem(MENU_ITEM_NORMAL);
      item->name = CopyString(_("Close"));
      item->action.type = MA_CLOSE | MA_GROUP_MASK;
      item->action.context = tp;
      item->next = menu->items;
      menu->items = item;

      item = CreateMenuItem(MENU_ITEM_NORMAL);
      item->name = CopyString(_("Minimize"));
      item->action.type = MA_MINIMIZE | MA_GROUP_MASK;
      item->action.context = tp;
      item->next = menu->items;
      menu->items = item;

      item = CreateMenuItem(MENU_ITEM_NORMAL);
      item->name = CopyString(_("Restore"));
      item->action.type = MA_RESTORE | MA_GROUP_MASK;
      item->action.context = tp;
      item->next = menu->items;
      menu->items = item;

      item = CreateMenuItem(MENU_ITEM_SUBMENU);
      item->name = CopyString(_("Send To"));
      item->action.type = MA_SENDTO_MENU | MA_GROUP_MASK;
      item->action.context = tp;
      item->next = menu->items;
      menu->items = item;

      /* Load the separator and group actions. */
      item = CreateMenuItem(MENU_ITEM_SEPARATOR);
      item->next = menu->items;
      menu->items = item;

      /* Load the clients into the menu. */
      for(cp = tp->clients; cp; cp = cp->next) {
         if(!ShouldFocus(cp->client, 0)) {
            continue;
         }
         item = CreateMenuItem(MENU_ITEM_NORMAL);
         if(cp->client->state.status & STAT_MINIMIZED) {
            size_t len = 0;
            if(cp->client->name) {
               len = strlen(cp->client->name);
            }
            item->name = Allocate(len + 3);
            item->name[0] = '[';
            memcpy(&item->name[1], cp->client->name, len);
            item->name[len + 1] = ']';
            item->name[len + 2] = 0;
         } else {
            item->name = CopyString(cp->client->name);
         }
         item->icon = cp->client->icon ? cp->client->icon : GetDefaultIcon();
         item->action.type = MA_EXECUTE;
         item->action.context = cp->client;
         item->next = menu->items;
         menu->items = item;
      }
   } else {
      /* Not grouping clients. */
      menu = CreateWindowMenu(tp->clients->client);
   }

   /* Initialize and position the menu. */
   InitializeMenu(menu);
   sp = GetCurrentScreen(bar->cp->screenx, bar->cp->screeny);
   GetMousePosition(&x, &y, &w);
   if(bar->layout == LAYOUT_HORIZONTAL) {
      if(bar->cp->screeny + bar->cp->height / 2 < sp->y + sp->height / 2) {
         /* Bottom of the screen: menus go up. */
         y = bar->cp->screeny + bar->cp->height;
      } else {
         /* Top of the screen: menus go down. */
         y = bar->cp->screeny - menu->height;
      }
      x -= menu->width / 2;
      x = Max(x, sp->x);
   } else {
      if(bar->cp->screenx + bar->cp->width / 2 < sp->x + sp->width / 2) {
         /* Left side: menus go right. */
         x = bar->cp->screenx + bar->cp->width;
      } else {
         /* Right side: menus go left. */
         x = bar->cp->screenx - menu->width;
      }
      y -= menu->height / 2;
      y = Max(y, sp->y);
   }

   ShowMenu(menu, RunTaskBarCommand, x, y, 0);

   DestroyMenu(menu);

}
Example #12
0
bool IK::Solve(Vector3 targetPos)
{
	//http://mrl.nyu.edu/~perlin/gdc/ik/ik.java.html

	//Get nodes
	Node* hip = effector_->GetParent()->GetParent();
	Node* knee = effector_->GetParent();

	// Get current world position for the 3 joints of the IK chain
	Vector3 hipPos = hip->GetWorldPosition(); // Thigh pos (hip joint)
	Vector3 kneePos = knee->GetWorldPosition(); // Calf pos (knee joint)
	Vector3 effectorPos = effector_->GetWorldPosition(); // Foot pos (ankle joint)

	// Pre IK Direction vectors
	Vector3 thighDir = kneePos - hipPos; // Thigh direction
	Vector3 calfDir = effectorPos - kneePos; // Calf direction	

	// Vectors lengths
	float A = Vector3(thighDir).Length();//length of hip to knee
	float B = Vector3(calfDir).Length();//length of knee to foot
	Vector3 P = hip->WorldToLocal(targetPos);//target at origin
	Vector3 D = hip->WorldToLocal(kneePos);//pre solve knee at origin
	//float limbLength = length1 + length2;
	//float lengthH = targetDir.Length();

	//PERLINS STUFF
	//bool test = Perlin(A,B,C,D);
	//GetSubsystem<DebugHud>()->SetAppStats("ik:", String(test) );
	//------
	Vector3 R;
	DefineM(P,D);
	R = Rot(Minv,P);
	//FIND D
	float c = R.Length();
    float d = Max(0.0f, Min(A, (c + (A*A-B*B)/c) / 2.0f));//FindD(A,B,R.Length());
    //FIND E
    float e = sqrtf(A*A-d*d);//FindE(A,d);
    Vector3 S = Vector3(d,e,0.0f);
    Vector3 Q = Rot(Mfwd,S);

    //Convert Q back to world space
    Vector3 worldQ = effector_->GetParent()->GetParent()->LocalToWorld(Q);

    //Get angles
    Vector3 tdn = thighDir.Normalized();
    Vector3 ntdn = Vector3(worldQ-hipPos).Normalized();
    Vector3 cdn = calfDir.Normalized();
    Vector3 ncdn = Vector3(targetPos-worldQ).Normalized();

    //Vector3 hipAxis = tdn.CrossProduct(ntdn); 
    //float hipAngle = tdn.Angle(ntdn);
    //Vector3 kneeAxis = cdn.CrossProduct(ncdn);
    //float kneeAngle = cdn.Angle(ncdn);

    //GetSubsystem<DebugHud>()->SetAppStats("ik:", String(hipAngle)+":"+String(kneeAngle) );

    //knee->SetWorldRotation(knee->GetWorldRotation() * Quaternion(kneeAngle,kneeAxis) );
	//hip->SetWorldRotation(hip->GetWorldRotation() * Quaternion(hipAngle,hipAxis) );
	//do top level first, then get new angle for lower level, since it might mangle it
	bool success = d > 0.0f && d < A;

	if(success)
	{
		Quaternion hipRot = Quaternion(tdn,ntdn);
		hip->Rotate(hipRot,TS_WORLD );
		knee->Rotate(Quaternion(cdn,ncdn)*hipRot.Inverse(),TS_WORLD );
	}

    if(drawDebug_)
    {
	    DebugRenderer* dbg = effector_->GetScene()->GetComponent<DebugRenderer>();
	    
	    /*dbg->AddLine(hipPos,hipPos+tdn,Color(0.0f,1.0f,0.0f),false);
    	dbg->AddLine(hipPos,hipPos+ntdn,Color(0.0f,0.0f,1.0f),false);
	    dbg->AddLine(kneePos,kneePos+cdn,Color(0.0f,1.0f,0.0f),false);
    	dbg->AddLine(kneePos,kneePos+ncdn,Color(0.0f,0.0f,1.0f),false);

    	dbg->AddSphere(Sphere(effectorPos,0.2f),Color(0.0f,1.0f,0.0f),false);
    	dbg->AddSphere(Sphere(targetPos,0.2f),Color(0.0f,0.0f,1.0f),false);*/
	    //at origin
	    /*dbg->AddSphere(Sphere(Vector3(),0.2f),Color(0.0f,0.0f,0.0f),false);//origin
	    dbg->AddSphere(Sphere(D,0.2f),Color(0.1f,0.0f,0.0f),false);//old elbow
	    dbg->AddSphere(Sphere(P,0.2f),Color(0.0f,1.0f,0.0f),false);//target
	    dbg->AddLine(Vector3(),P,Color(0.1f,0.1f,0.1f),false);

	    //show solve at origin
	    dbg->AddSphere(Sphere(Q,0.2f),Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(Vector3(),Q,Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(Q,P,Color(1.0f,0.0f,0.0f),false);*/

		//show solve at position
		dbg->AddSphere(Sphere(worldQ,0.2f),Color(1.0f,0.0f,0.0f),false);
		dbg->AddSphere(Sphere(targetPos,0.2f),Color(0.0f,1.0f,0.0f),false);
		dbg->AddLine(hipPos,worldQ,Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(worldQ,targetPos,Color(1.0f,0.0f,0.0f),false);
	}

    return success;

	
}
Example #13
0
void CObject::ObjectDamage(float damage, CVector* vec1, CVector* vec2, CEntity* damager, eWeaponType weapon_type)
{
    if(m_bUsesCollision)
    {
        return;
    }
    if(weapon_type == 55 && damager && damager->entityType == ENTITY_TYPE_VEHICLE)
    {
        weapon_type == 50;
    }
    if(!CanPhysicalBeDamaged(weapon_type, NULL))
    {
        return;
    }
    m_fHealth = Max(m_fHealth - damage * m_pObjectInfo->fColDamageMultiplier, 0.0);
    if(m_colDamageEffect == 0 || (m_bInvulnerable && damager != getPlayerPed(-1) && damager != getPlayerVehicle(-1, 0)))
    {
        return;
    }
    if(m_nModelIndex == MODEL_INDEX_IMY_SMASH_WALL)
    {
        // vehicle must be SWAT Water Cannon Vehicle
        CVehicle *veh = damager;
        if(!veh)
        {
            return;
        }
        switch(damager->entityType)
        {
            case ENTITY_TYPE_PED:
                if(!damager->pedFlags.bInVehicle || !damager->pCurrentObjective)
                {
                    return;
                }
                veh = damager->pCurrentObjective;
            break;
            case ENTITY_TYPE_VEHICLE:
            break;
            default:
                return;
        }
        if(veh->m_nModelIndex != 601)
        {
            return;
        }
    }
    // must not be a Forklift
    if(damager && damager->m_nModelIndex == MODEL_INDEX_FORKLIFT)
    {
        return;
    }
    m_breakWeaponType = weapon_type;
    if(damage * m_pObject->fColDamageMultiplier > 150.0)
    {
        switch(m_colDamageEffect)
        {
            case 200:
            case 202:
            {
                bool smashed = false;
                if(m_pObjectInfo->fSmashMultiplier * 150.0 < damage * m_pObjectInfo->fColDamageMultiplier)
                {
                    smashed = true;
                }
                BreakableInfoPool.Add(this, m_pObjectInfo->breakVelocity, m_pObjectInfo->fBreakVelocityRand, smashed);
                m_bUsesCollision = false;
                m_bIsVisible = false;
                if(!IsStatic())
                {
                    RemoveFromMovingList();
                }
                m_bExplosionProof = true;
                m_bIsStatic = true;
                m_vecLinearVelocity = 0;
                m_vecAngularVelocity = 0;
                m_bBroken = true;
                DeleteRwObject();
                v14 = 1; // v14: advancedDamage ( needs audio + explosion) # basic is only fx
            }
            break;
            case 1:
                if(!bRenderDamaged)
                {
                    DeleteRwObject();
                    v14 = 1;
                }
            break;
            case 20:
                m_bUsesCollision = false;
                m_bIsVisible = false;
                if(!IsStatic())
                {
                    RemoveFromMovingList();
                }
                m_bIsStatic = true;
                m_bExplosionProof = true;
                m_vecLinearVelocity = 0;
                m_vecAngularVelocity = 0;
                DeleteRwObject();
                v14 = 1;
            break;
            case 21:
                if(m_bRenderDamaged)
                {
                    m_bUsesCollision = false;
                    m_bIsVisible = false;
                    if(!IsStatic())
                    {
                        RemoveFromMovingList();
                    }
                    m_bIsStatic = true;
                    m_bExplosionProof = true;
                    m_vecLinearVelocity = 0;
                    m_vecAngularVelocity = 0;
                    DeleteRwObject();
                    v14 = 1;
                }
                else
                {
                    DeleteRwObject();
                    m_bRenderDamaged = true;
                }
            break;
        }
        if(m_bUsesCollision && m_bIsVisible)
        {
            m_fHealth = 0.0;
        }
    }
    bool exploded = false;
    if(v14 == 1)
    {
        if(TryToExplode())
        {
            exploded = true;
        }
        CAudio::ProcessBrokenObject(this);
    }
    if(!exploded || !v14)
    {
        v27 = m_pObjectInfo->fxType == 3;
        if(v14 == 0)
        {
            if(m_pObjectInfo->fxType != 1)
            {
                return;
            }
            v27 = damage > 30.0;
        }
        else
        {
            v27 = m_pObjectInfo->fxType == 2;
        }
        if(v27)
        {
            if(m_pObjectInfo->fxOffset.x >= -500.0)
            {
                CMatrix pos = CMatrix::FromXYZ(m_xyz);
                // to object space
                CVector fx_obj_pos = pos * m_pObjectInfo->fxOffset;
                fx_obj_pos += GetPos(); // to world space
                FxSystem_c *sys = FxManager.InitialiseFxSystem(m_pObjectInfo->pFxSystemBP, fx_obj_pos, 0, 0);
                if(sys)
                {
                    sys->Start();
                }    
            }
            else
            {
                if(!offset)
                {
                    return;
                }
                RwMatrix matrix;
                Fx_c::CreateMatFromVec(matrix, offset, rotation);
                FxSystem_c *sys = FxManager.InitialiseFxSystem(m_pObjectInfo->pFxSystemBP, matrix, 0, 0);
                if(sys)
                {
                    sys->Start();
                }
            }
        }
    }
}
EXPORT_C void CSdpAttrIdMatchList::AddL(TAttrRange aRange)
/** Adds a range of IDs to the list.

@param aRange Range to add */
	{
	if (aRange.iStart > aRange.iEnd)
		{// Bad range
		User::Leave(KErrArgument);
		}
		
		
	// Look for insertion point (pos) in the match list. 
		
	TInt pos = 0; 	// this new item will start the list unless we find an existing
					// range for it to overlap or follow

	// If the start of the range 'aRange' is contiguous with one of the existing match list ranges
	// then the insertion point is the index of that match list range.
	// If not it is one more than the index of the match list range that
	// precedes 'aRange'.
	// N.B. The ranges are stored in ascending order

	TBool bPositionFound = EFalse;
	TBool bStartInRangeOrContiguous = EFalse;	

	// Find the first position in the list in which (or contiguous with) this range lies
	if (FindInOrContiguousWith(aRange.iStart, pos) == 0)
		{
		// the start of this new range overlaps with an existing one (returned in pos) or is contiguous with it
		bPositionFound = ETrue;
		bStartInRangeOrContiguous = ETrue;
		}	
	else
		{
		// find which range this new one will be after
		for (TInt i=iList->Count()-1; i>=0 && !bPositionFound; i-- )
			{
			if (aRange.iStart > (iList->At(i).iEnd + 1 ))
				{
				pos = i+1;
				bPositionFound = ETrue;
				}
			}
		}

	TAttrRange *insert;
	
	if (bStartInRangeOrContiguous)
		{// Don't actually insert new entry, just grow the existing entry
		insert = &iList->At(pos);
		
		// NB If the range to add has a start ID which is one less than the current start of range, 
		// the range may grow "downwards", but will never join up with the preceding range because
		// the start ID is known not to be contiguous with THAT range.
		insert->iStart = Min(insert->iStart, aRange.iStart); 
		insert->iEnd = Max(insert->iEnd, aRange.iEnd);
		}
	else
		{// Add a new entry
		iList->InsertL(pos, aRange);
		insert = &iList->At(pos);
		}

	while (pos < iList->Count()-1 && insert->IsContiguousWith(iList->At(pos+1).iStart) )
		{// There's now overlap with following item
		insert->iEnd = Max(insert->iEnd, iList->At(pos+1).iEnd);
		iList->Delete(pos+1);	// which leaves a new range to be checked at (pos+1), so no incrementing of pos is required	
		}
	__TEST_INVARIANT;
	}
Example #15
0
void Button::SetRepeatRate(float rate)
{
    repeatRate_ = Max(rate, 0.0f);
}
Example #16
0
/*
 * helpSQL -- help with SQL commands
 *
 * Note: we assume caller removed any trailing spaces in "topic".
 */
void
helpSQL(const char *topic, unsigned short int pager)
{
#define VALUE_OR_NULL(a) ((a) ? (a) : "")

    if (!topic || strlen(topic) == 0)
    {
        /* Print all the available command names */
        int			screen_width;
        int			ncolumns;
        int			nrows;
        FILE	   *output;
        int			i;
        int			j;

#ifdef TIOCGWINSZ
        struct winsize screen_size;

        if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1)
            screen_width = 80;	/* ioctl failed, assume 80 */
        else
            screen_width = screen_size.ws_col;
#else
        screen_width = 80;		/* default assumption */
#endif

        ncolumns = (screen_width - 3) / (QL_MAX_CMD_LEN + 1);
        ncolumns = Max(ncolumns, 1);
        nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns;

        output = PageOutput(nrows + 1, pager);

        fputs(_("Available help:\n"), output);

        for (i = 0; i < nrows; i++)
        {
            fprintf(output, "  ");
            for (j = 0; j < ncolumns - 1; j++)
                fprintf(output, "%-*s",
                        QL_MAX_CMD_LEN + 1,
                        VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
            if (i + j * nrows < QL_HELP_COUNT)
                fprintf(output, "%s",
                        VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
            fputc('\n', output);
        }

        ClosePager(output);
    }
    else
    {
        int			i,
                    j,
                    x = 0;
        bool		help_found = false;
        FILE	   *output = NULL;
        size_t		len,
                    wordlen;
        int			nl_count = 0;

        /*
         * We first try exact match, then first + second words, then first
         * word only.
         */
        len = strlen(topic);

        for (x = 1; x <= 3; x++)
        {
            if (x > 1)			/* Nothing on first pass - try the opening
								 * word(s) */
            {
                wordlen = j = 1;
                while (topic[j] != ' ' && j++ < len)
                    wordlen++;
                if (x == 2)
                {
                    j++;
                    while (topic[j] != ' ' && j++ <= len)
                        wordlen++;
                }
                if (wordlen >= len)		/* Don't try again if the same word */
                {
                    if (!output)
                        output = PageOutput(nl_count, pager);
                    break;
                }
                len = wordlen;
            }

            /* Count newlines for pager */
            for (i = 0; QL_HELP[i].cmd; i++)
            {
                if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
                        strcmp(topic, "*") == 0)
                {
                    nl_count += 5 + QL_HELP[i].nl_count;

                    /* If we have an exact match, exit.  Fixes \h SELECT */
                    if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0)
                        break;
                }
            }

            if (!output)
                output = PageOutput(nl_count, pager);

            for (i = 0; QL_HELP[i].cmd; i++)
            {
                if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
                        strcmp(topic, "*") == 0)
                {
                    PQExpBufferData buffer;

                    initPQExpBuffer(&buffer);
                    QL_HELP[i].syntaxfunc(&buffer);
                    help_found = true;
                    fprintf(output, _("Command:     %s\n"
                                      "Description: %s\n"
                                      "Syntax:\n%s\n\n"),
                            QL_HELP[i].cmd,
                            _(QL_HELP[i].help),
                            buffer.data);
                    /* If we have an exact match, exit.  Fixes \h SELECT */
                    if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0)
                        break;
                }
            }
            if (help_found)		/* Don't keep trying if we got a match */
                break;
        }

        if (!help_found)
            fprintf(output, _("No help available for \"%s\".\nTry \\h with no arguments to see available help.\n"), topic);

        ClosePager(output);
    }
}
Example #17
0
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
                                     const char* title,
                                     GLFWmonitor* monitor,
                                     GLFWwindow* share)
{
    _GLFWfbconfig fbconfig;
    _GLFWwndconfig wndconfig;
    _GLFWwindow* window;
    _GLFWwindow* previous;

    _GLFW_REQUIRE_INIT_OR_RETURN(NULL);

    if (width <= 0 || height <= 0)
    {
        _glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");
        return NULL;
    }

    // Set up desired framebuffer config
    fbconfig.redBits        = Max(_glfw.hints.redBits, 0);
    fbconfig.greenBits      = Max(_glfw.hints.greenBits, 0);
    fbconfig.blueBits       = Max(_glfw.hints.blueBits, 0);
    fbconfig.alphaBits      = Max(_glfw.hints.alphaBits, 0);
    fbconfig.depthBits      = Max(_glfw.hints.depthBits, 0);
    fbconfig.stencilBits    = Max(_glfw.hints.stencilBits, 0);
    fbconfig.accumRedBits   = Max(_glfw.hints.accumRedBits, 0);
    fbconfig.accumGreenBits = Max(_glfw.hints.accumGreenBits, 0);
    fbconfig.accumBlueBits  = Max(_glfw.hints.accumBlueBits, 0);
    fbconfig.accumAlphaBits = Max(_glfw.hints.accumAlphaBits, 0);
    fbconfig.auxBuffers     = Max(_glfw.hints.auxBuffers, 0);
    fbconfig.stereo         = _glfw.hints.stereo ? GL_TRUE : GL_FALSE;
    fbconfig.samples        = Max(_glfw.hints.samples, 0);
    fbconfig.sRGB           = _glfw.hints.sRGB ? GL_TRUE : GL_FALSE;

    // Set up desired window config
    wndconfig.width         = width;
    wndconfig.height        = height;
    wndconfig.title         = title;
    wndconfig.resizable     = _glfw.hints.resizable ? GL_TRUE : GL_FALSE;
    wndconfig.visible       = _glfw.hints.visible ? GL_TRUE : GL_FALSE;
    wndconfig.decorated     = _glfw.hints.decorated ? GL_TRUE : GL_FALSE;
    wndconfig.clientAPI     = _glfw.hints.clientAPI;
    wndconfig.glMajor       = _glfw.hints.glMajor;
    wndconfig.glMinor       = _glfw.hints.glMinor;
    wndconfig.glForward     = _glfw.hints.glForward ? GL_TRUE : GL_FALSE;
    wndconfig.glDebug       = _glfw.hints.glDebug ? GL_TRUE : GL_FALSE;
    wndconfig.glProfile     = _glfw.hints.glProfile;
    wndconfig.glRobustness  = _glfw.hints.glRobustness;
    wndconfig.monitor       = (_GLFWmonitor*) monitor;
    wndconfig.share         = (_GLFWwindow*) share;

    // Check the OpenGL bits of the window config
    if (!_glfwIsValidContextConfig(&wndconfig))
        return NULL;

    window = calloc(1, sizeof(_GLFWwindow));
    window->next = _glfw.windowListHead;
    _glfw.windowListHead = window;

    if (wndconfig.monitor)
    {
        wndconfig.resizable = GL_TRUE;
        wndconfig.visible   = GL_TRUE;

        // Set up desired video mode
        window->videoMode.width       = width;
        window->videoMode.height      = height;
        window->videoMode.redBits     = Max(_glfw.hints.redBits, 0);
        window->videoMode.greenBits   = Max(_glfw.hints.greenBits, 0);
        window->videoMode.blueBits    = Max(_glfw.hints.blueBits, 0);
        window->videoMode.refreshRate = Max(_glfw.hints.refreshRate, 0);
    }

    window->monitor     = wndconfig.monitor;
    window->resizable   = wndconfig.resizable;
    window->decorated   = wndconfig.decorated;
    window->cursorMode  = GLFW_CURSOR_NORMAL;

    // Save the currently current context so it can be restored later
    previous = (_GLFWwindow*) glfwGetCurrentContext();

    // Open the actual window and create its context
    if (!_glfwPlatformCreateWindow(window, &wndconfig, &fbconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return NULL;
    }

    glfwMakeContextCurrent((GLFWwindow*) window);

    // Retrieve the actual (as opposed to requested) context attributes
    if (!_glfwRefreshContextAttribs())
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return NULL;
    }

    // Verify the context against the requested parameters
    if (!_glfwIsValidContext(&wndconfig))
    {
        glfwDestroyWindow((GLFWwindow*) window);
        glfwMakeContextCurrent((GLFWwindow*) previous);
        return NULL;
    }

    // Clearing the front buffer to black to avoid garbage pixels left over
    // from previous uses of our bit of VRAM
    glClear(GL_COLOR_BUFFER_BIT);
    _glfwPlatformSwapBuffers(window);

    // Restore the previously current context (or NULL)
    glfwMakeContextCurrent((GLFWwindow*) previous);

    if (wndconfig.monitor == NULL && wndconfig.visible)
        glfwShowWindow((GLFWwindow*) window);

    return (GLFWwindow*) window;
}
Example #18
0
void L3psycho_anal( lame_global_flags *gfp,
                    short int *buffer[2],int gr_out , 
                    FLOAT8 *ms_ratio,
                    FLOAT8 *ms_ratio_next,
		    FLOAT8 *ms_ener_ratio,
		    III_psy_ratio masking_ratio[2][2],
		    III_psy_ratio masking_MS_ratio[2][2],
		    FLOAT8 percep_entropy[2],FLOAT8 percep_MS_entropy[2], 
                    int blocktype_d[2])
{

/* to get a good cache performance, one has to think about
 * the sequence, in which the variables are used
 */
  
/* The static variables "r", "phi_sav", "new", "old" and "oldest" have    */
/* to be remembered for the unpredictability measure.  For "r" and        */
/* "phi_sav", the first index from the left is the channel select and     */
/* the second index is the "age" of the data.                             */
  static FLOAT8	minval[CBANDS],qthr_l[CBANDS];
  static FLOAT8	qthr_s[CBANDS];
  static FLOAT8	nb_1[4][CBANDS], nb_2[4][CBANDS];
  static FLOAT8 s3_s[CBANDS + 1][CBANDS + 1];
  static FLOAT8 s3_l[CBANDS + 1][CBANDS + 1];

  static III_psy_xmin thm[4];
  static III_psy_xmin en[4];
  
  /* unpredictability calculation
   */
  static int cw_upper_index;
  static int cw_lower_index;
  static FLOAT ax_sav[4][2][HBLKSIZE];
  static FLOAT bx_sav[4][2][HBLKSIZE];
  static FLOAT rx_sav[4][2][HBLKSIZE];
  static FLOAT cw[HBLKSIZE];

  /* fft and energy calculation
   */
  FLOAT (*wsamp_l)[BLKSIZE];
  FLOAT (*wsamp_s)[3][BLKSIZE_s];
  FLOAT tot_ener[4];
  static FLOAT wsamp_L[2][BLKSIZE];
  static FLOAT energy[HBLKSIZE];
  static FLOAT wsamp_S[2][3][BLKSIZE_s];
  static FLOAT energy_s[3][HBLKSIZE_s];

  /* convolution
   */
  static FLOAT8 eb[CBANDS];
  static FLOAT8 cb[CBANDS];
  static FLOAT8 thr[CBANDS];
  
  /* Scale Factor Bands
   */
  static FLOAT8	w1_l[SBPSY_l], w2_l[SBPSY_l];
  static FLOAT8	w1_s[SBPSY_s], w2_s[SBPSY_s];
  static FLOAT8 mld_l[SBPSY_l],mld_s[SBPSY_s];
  static int	bu_l[SBPSY_l],bo_l[SBPSY_l] ;
  static int	bu_s[SBPSY_s],bo_s[SBPSY_s] ;
  static int	npart_l,npart_s;
  static int	npart_l_orig,npart_s_orig;
  
  static int	s3ind[CBANDS][2];
  static int	s3ind_s[CBANDS][2];

  static int	numlines_s[CBANDS] ;
  static int	numlines_l[CBANDS];
  static int	partition_l[HBLKSIZE];
  
  /* frame analyzer 
   */
#ifdef HAVEGTK
  static FLOAT energy_save[4][HBLKSIZE];
  static FLOAT8 pe_save[4];
  static FLOAT8 ers_save[4];
#endif

  /* ratios 
   */
  static FLOAT8 pe[4]={0,0,0,0};
  static FLOAT8 ms_ratio_s_old=0,ms_ratio_l_old=0;
  static FLOAT8 ms_ener_ratio_old=.25;
  FLOAT8 ms_ratio_l=0,ms_ratio_s=0;

  /* block type 
   */
  static int	blocktype_old[2];
  int blocktype[2],uselongblock[2];
  
  /* usual variables like loop indices, etc..
   */
  int numchn, chn;
  int   b, i, j, k;
  int	sb,sblock;
  FLOAT cwlimit;


  /* initialization of static variables
   */
  if((gfp->frameNum==0) && (gr_out==0)){
    FLOAT8	SNR_s[CBANDS];
    
    blocktype_old[0]=STOP_TYPE;
    blocktype_old[1]=STOP_TYPE;
    i = gfp->out_samplerate;
    switch(i){
    case 32000: break;
    case 44100: break;
    case 48000: break;
    case 16000: break;
    case 22050: break;
    case 24000: break;
    default:    fprintf(stderr,"error, invalid sampling frequency: %d Hz\n",i);
      exit(-1);
    }
    
    /* reset states used in unpredictability measure */
    memset (rx_sav,0, sizeof(rx_sav));
    memset (ax_sav,0, sizeof(ax_sav));
    memset (bx_sav,0, sizeof(bx_sav));
    memset (en,0, sizeof(en));
    memset (thm,0, sizeof(thm));
    

    /*  gfp->cwlimit = sfreq*j/1024.0;  */
    cw_lower_index=6;
    if (gfp->cwlimit>0) 
      cwlimit=gfp->cwlimit;
    else
      cwlimit=8.8717;
    cw_upper_index = cwlimit*1000.0*1024.0/((FLOAT8) gfp->out_samplerate);
    cw_upper_index=Min(HBLKSIZE-4,cw_upper_index);      /* j+3 < HBLKSIZE-1 */
    cw_upper_index=Max(6,cw_upper_index);

    for ( j = 0; j < HBLKSIZE; j++ )
      cw[j] = 0.4;
    
    /* setup stereo demasking thresholds */
    /* formula reverse enginerred from plot in paper */
    for ( sb = 0; sb < SBPSY_s; sb++ ) {
      FLOAT8 mld = 1.25*(1-cos(PI*sb/SBPSY_s))-2.5;
      mld_s[sb] = pow(10.0,mld);
    }
    for ( sb = 0; sb < SBPSY_l; sb++ ) {
      FLOAT8 mld = 1.25*(1-cos(PI*sb/SBPSY_l))-2.5;
      mld_l[sb] = pow(10.0,mld);
    }
    
    for (i=0;i<HBLKSIZE;i++) partition_l[i]=-1;

    L3para_read( (FLOAT8) gfp->out_samplerate,numlines_l,numlines_s,partition_l,minval,qthr_l,s3_l,s3_s,
		 qthr_s,SNR_s,
		 bu_l,bo_l,w1_l,w2_l, bu_s,bo_s,w1_s,w2_s );
    
    
    /* npart_l_orig   = number of partition bands before convolution */
    /* npart_l  = number of partition bands after convolution */
    npart_l_orig=0; npart_s_orig=0;
    for (i=0;i<HBLKSIZE;i++) 
      if (partition_l[i]>npart_l_orig) npart_l_orig=partition_l[i];
    npart_l_orig++;

    for (i=0;numlines_s[i]>=0;i++)
      ;
    npart_s_orig = i;
    
    npart_l=bo_l[SBPSY_l-1]+1;
    npart_s=bo_s[SBPSY_s-1]+1;

    /* MPEG2 tables are screwed up 
     * the mapping from paritition bands to scalefactor bands will use
     * more paritition bands than we have.  
     * So we will not compute these fictitious partition bands by reducing
     * npart_l below.  */
    if (npart_l > npart_l_orig) {
      npart_l=npart_l_orig;
      bo_l[SBPSY_l-1]=npart_l-1;
      w2_l[SBPSY_l-1]=1.0;
    }
    if (npart_s > npart_s_orig) {
      npart_s=npart_s_orig;
      bo_s[SBPSY_s-1]=npart_s-1;
      w2_s[SBPSY_s-1]=1.0;
    }
    
    
    
    for (i=0; i<npart_l; i++) {
      for (j = 0; j < npart_l_orig; j++) {
	if (s3_l[i][j] != 0.0)
	  break;
      }
      s3ind[i][0] = j;
      
      for (j = npart_l_orig - 1; j > 0; j--) {
	if (s3_l[i][j] != 0.0)
	  break;
      }
      s3ind[i][1] = j;
    }


    for (i=0; i<npart_s; i++) {
      for (j = 0; j < npart_s_orig; j++) {
	if (s3_s[i][j] != 0.0)
	  break;
      }
      s3ind_s[i][0] = j;
      
      for (j = npart_s_orig - 1; j > 0; j--) {
	if (s3_s[i][j] != 0.0)
	  break;
      }
      s3ind_s[i][1] = j;
    }
    
    
    /*  
      #include "debugscalefac.c"
    */
    

#define AACS3
#define NEWS3XX

#ifdef AACS3
    /* AAC values, results in more masking over MP3 values */
# define TMN 18
# define NMT 6
#else
    /* MP3 values */
# define TMN 29
# define NMT 6
#endif

#define rpelev 2
#define rpelev2 16

    /* compute norm_l, norm_s instead of relying on table data */
    for ( b = 0;b < npart_l; b++ ) {
      FLOAT8 norm=0;
      for ( k = s3ind[b][0]; k <= s3ind[b][1]; k++ ) {
	norm += s3_l[b][k];
      }
      for ( k = s3ind[b][0]; k <= s3ind[b][1]; k++ ) {
	s3_l[b][k] *= exp(-LN_TO_LOG10 * NMT) / norm;
      }
      /*printf("%i  norm=%f  norm_l=%f \n",b,1/norm,norm_l[b]);*/
    }

    /* MPEG1 SNR_s data is given in db, convert to energy */
    if (gfp->version == 1) {
      for ( b = 0;b < npart_s; b++ ) {
	SNR_s[b]=exp( (FLOAT8) SNR_s[b] * LN_TO_LOG10 );
      }
    }

    for ( b = 0;b < npart_s; b++ ) {
      FLOAT8 norm=0;
      for ( k = s3ind_s[b][0]; k <= s3ind_s[b][1]; k++ ) {
	norm += s3_s[b][k];
      }
      for ( k = s3ind_s[b][0]; k <= s3ind_s[b][1]; k++ ) {
	s3_s[b][k] *= SNR_s[b] / norm;
      }
      /*printf("%i  norm=%f  norm_s=%f \n",b,1/norm,norm_l[b]);*/
    }
    
    init_fft();
  }
  /************************* End of Initialization *****************************/
  


  
  
  numchn = gfp->stereo;
  /* chn=2 and 3 = Mid and Side channels */
  if (gfp->mode == MPG_MD_JOINT_STEREO) numchn=4;
  for (chn=0; chn<numchn; chn++) {
  
    wsamp_s = wsamp_S+(chn & 1);
    wsamp_l = wsamp_L+(chn & 1);


    if (chn<2) {    
      /**********************************************************************
       *  compute FFTs
       **********************************************************************/
      fft_long ( *wsamp_l, chn, buffer);
      fft_short( *wsamp_s, chn, buffer); 
      
      /* LR maskings  */
      percep_entropy[chn] = pe[chn]; 
      masking_ratio[gr_out][chn].thm = thm[chn];
      masking_ratio[gr_out][chn].en = en[chn];
    }else{
      /* MS maskings  */
      percep_MS_entropy[chn-2] = pe[chn]; 
      masking_MS_ratio[gr_out][chn-2].en = en[chn];
      masking_MS_ratio[gr_out][chn-2].thm = thm[chn];
      
      if (chn == 2)
      {
        for (j = BLKSIZE-1; j >=0 ; --j)
        {
          FLOAT l = wsamp_L[0][j];
          FLOAT r = wsamp_L[1][j];
          wsamp_L[0][j] = (l+r)*(FLOAT)(SQRT2*0.5);
          wsamp_L[1][j] = (l-r)*(FLOAT)(SQRT2*0.5);
        }
        for (b = 2; b >= 0; --b)
        {
          for (j = BLKSIZE_s-1; j >= 0 ; --j)
          {
            FLOAT l = wsamp_S[0][b][j];
            FLOAT r = wsamp_S[1][b][j];
            wsamp_S[0][b][j] = (l+r)*(FLOAT)(SQRT2*0.5);
            wsamp_S[1][b][j] = (l-r)*(FLOAT)(SQRT2*0.5);
          }
        }
      }
    }

    /**********************************************************************
     *  compute energies
     **********************************************************************/
    
    
    
    energy[0]  = (*wsamp_l)[0];
    energy[0] *= energy[0];
    
    tot_ener[chn] = energy[0]; /* sum total energy at nearly no extra cost */
    
    for (j=BLKSIZE/2-1; j >= 0; --j)
    {
      FLOAT re = (*wsamp_l)[BLKSIZE/2-j];
      FLOAT im = (*wsamp_l)[BLKSIZE/2+j];
      energy[BLKSIZE/2-j] = (re * re + im * im) * (FLOAT)0.5;
      
      tot_ener[chn] += energy[BLKSIZE/2-j];
    }
    for (b = 2; b >= 0; --b)
    {
      energy_s[b][0]  = (*wsamp_s)[b][0];
      energy_s[b][0] *=  energy_s [b][0];
      for (j=BLKSIZE_s/2-1; j >= 0; --j)
      {
        FLOAT re = (*wsamp_s)[b][BLKSIZE_s/2-j];
        FLOAT im = (*wsamp_s)[b][BLKSIZE_s/2+j];
        energy_s[b][BLKSIZE_s/2-j] = (re * re + im * im) * (FLOAT)0.5;
      }
    }


#ifdef HAVEGTK
  if(gfp->gtkflag) {
    for (j=0; j<HBLKSIZE ; j++) {
      pinfo->energy[gr_out][chn][j]=energy_save[chn][j];
      energy_save[chn][j]=energy[j];
    }
  }
#endif
    
    /**********************************************************************
     *    compute unpredicatability of first six spectral lines            * 
     **********************************************************************/
    for ( j = 0; j < cw_lower_index; j++ )
      {	 /* calculate unpredictability measure cw */
	FLOAT an, a1, a2;
	FLOAT bn, b1, b2;
	FLOAT rn, r1, r2;
	FLOAT numre, numim, den;

	a2 = ax_sav[chn][1][j];
	b2 = bx_sav[chn][1][j];
	r2 = rx_sav[chn][1][j];
	a1 = ax_sav[chn][1][j] = ax_sav[chn][0][j];
	b1 = bx_sav[chn][1][j] = bx_sav[chn][0][j];
	r1 = rx_sav[chn][1][j] = rx_sav[chn][0][j];
	an = ax_sav[chn][0][j] = (*wsamp_l)[j];
	bn = bx_sav[chn][0][j] = j==0 ? (*wsamp_l)[0] : (*wsamp_l)[BLKSIZE-j];  
	rn = rx_sav[chn][0][j] = sqrt(energy[j]);

	{ /* square (x1,y1) */
	  if( r1 != 0 ) {
	    numre = (a1*b1);
	    numim = (a1*a1-b1*b1)*(FLOAT)0.5;
	    den = r1*r1;
	  } else {
	    numre = 1;
	    numim = 0;
	    den = 1;
	  }
	}
	
	{ /* multiply by (x2,-y2) */
	  if( r2 != 0 ) {
	    FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;
	    FLOAT tmp1 = -a2*numre+tmp2;
	    numre =       -b2*numim+tmp2;
	    numim = tmp1;
	    den *= r2;
	  } else {
	    /* do nothing */
	  }
	}
	
	{ /* r-prime factor */
	  FLOAT tmp = (2*r1-r2)/den;
	  numre *= tmp;
	  numim *= tmp;
	}
	den=rn+fabs(2*r1-r2);
	if( den != 0 ) {
	  numre = (an+bn)*(FLOAT)0.5-numre;
	  numim = (an-bn)*(FLOAT)0.5-numim;
	  den = sqrt(numre*numre+numim*numim)/den;
	}
	cw[j] = den;
      }



    /**********************************************************************
     *     compute unpredicatibility of next 200 spectral lines            *
     **********************************************************************/ 
    for ( j = cw_lower_index; j < cw_upper_index; j += 4 )
      {/* calculate unpredictability measure cw */
	FLOAT rn, r1, r2;
	FLOAT numre, numim, den;
	
	k = (j+2) / 4; 
	
	{ /* square (x1,y1) */
	  r1 = energy_s[0][k];
	  if( r1 != 0 ) {
	    FLOAT a1 = (*wsamp_s)[0][k]; 
	    FLOAT b1 = (*wsamp_s)[0][BLKSIZE_s-k]; /* k is never 0 */
	    numre = (a1*b1);
	    numim = (a1*a1-b1*b1)*(FLOAT)0.5;
	    den = r1;
	    r1 = sqrt(r1);
	  } else {
	    numre = 1;
	    numim = 0;
	    den = 1;
	  }
	}
	
	
	{ /* multiply by (x2,-y2) */
	  r2 = energy_s[2][k];
	  if( r2 != 0 ) {
	    FLOAT a2 = (*wsamp_s)[2][k]; 
	    FLOAT b2 = (*wsamp_s)[2][BLKSIZE_s-k];
	    
	    
	    FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;
	    FLOAT tmp1 = -a2*numre+tmp2;
	    numre =       -b2*numim+tmp2;
	    numim = tmp1;
	    
	    r2 = sqrt(r2);
	    den *= r2;
	  } else {
	    /* do nothing */
	  }
	}
	
	{ /* r-prime factor */
	  FLOAT tmp = (2*r1-r2)/den;
	  numre *= tmp;
	  numim *= tmp;
	}
	
	rn = sqrt(energy_s[1][k]);
	den=rn+fabs(2*r1-r2);
	if( den != 0 ) {
	  FLOAT an = (*wsamp_s)[1][k]; 
	  FLOAT bn = (*wsamp_s)[1][BLKSIZE_s-k];
	  numre = (an+bn)*(FLOAT)0.5-numre;
	  numim = (an-bn)*(FLOAT)0.5-numim;
	  den = sqrt(numre*numre+numim*numim)/den;
	}
	
	cw[j+1] = cw[j+2] = cw[j+3] = cw[j] = den;
      }
    
#if 0
    for ( j = 14; j < HBLKSIZE-4; j += 4 )
      {/* calculate energy from short ffts */
	FLOAT8 tot,ave;
	k = (j+2) / 4; 
	for (tot=0, sblock=0; sblock < 3; sblock++)
	  tot+=energy_s[sblock][k];
	ave = energy[j+1]+ energy[j+2]+ energy[j+3]+ energy[j];
	ave /= 4.;
	/*
	  printf("energy / tot %i %5.2f   %e  %e\n",j,ave/(tot*16./3.),
	  ave,tot*16./3.);
	*/
	energy[j+1] = energy[j+2] = energy[j+3] =  energy[j]=tot;
      }
#endif
    
    
    
    
    
    
    
    
    /**********************************************************************
     *    Calculate the energy and the unpredictability in the threshold   *
     *    calculation partitions                                           *
     **********************************************************************/
#if 0
    for ( b = 0; b < CBANDS; b++ )
      {
	eb[b] = 0;
	cb[b] = 0;
      }
    for ( j = 0; j < HBLKSIZE; j++ )
      {
	int tp = partition_l[j];
	
	if ( tp >= 0 )
	  {
	    eb[tp] += energy[j];
	    cb[tp] += cw[j] * energy[j];
	  }
	assert(tp<npart_l_orig);
      }
#else
    b = 0;
    for (j = 0; j < cw_upper_index;)
      {
	FLOAT8 ebb, cbb;
	int i;

	ebb = energy[j];
	cbb = energy[j] * cw[j];
	j++;

	for (i = numlines_l[b] - 1; i > 0; i--)
	  {
	    ebb += energy[j];
	    cbb += energy[j] * cw[j];
	    j++;
	  }
	eb[b] = ebb;
	cb[b] = cbb;
	b++;
      }

    for (; b < npart_l_orig; b++ )
      {
	int i;
	FLOAT8 ebb = energy[j++];

	for (i = numlines_l[b] - 1; i > 0; i--)
	  {
	    ebb += energy[j++];
	  }
	eb[b] = ebb;
	cb[b] = ebb * 0.4;
      }
#endif

    /**********************************************************************
     *      convolve the partitioned energy and unpredictability           *
     *      with the spreading function, s3_l[b][k]                        *
     ******************************************************************** */
    pe[chn] = 0;		/*  calculate percetual entropy */
    for ( b = 0;b < npart_l; b++ )
      {
	FLOAT8 tbb,ecb,ctb;
	FLOAT8 temp_1; /* BUG of IS */

	ecb = 0;
	ctb = 0;
	for ( k = s3ind[b][0]; k <= s3ind[b][1]; k++ )
	  {
	    ecb += s3_l[b][k] * eb[k];	/* sprdngf for Layer III */
	    ctb += s3_l[b][k] * cb[k];
	  }

	/* calculate the tonality of each threshold calculation partition */
	/* calculate the SNR in each threshhold calculation partition */

	tbb = ecb;
	if (tbb != 0)
	  {
	    tbb = ctb / tbb;
	    if (tbb <= 0.04875584301)
	      {
		tbb = exp(-LN_TO_LOG10 * (TMN - NMT));
	      }
	    else if (tbb > 0.4989003827)
	      {
		tbb = 1;
	      }
	    else
	      {
		tbb = log(tbb);
		tbb = exp(((TMN - NMT)*(LN_TO_LOG10*0.299))
			+ ((TMN - NMT)*(LN_TO_LOG10*0.43 ))*tbb);  /* conv1=-0.299, conv2=-0.43 */
	      }
	  }

	tbb = Min(minval[b], tbb);
	ecb *= tbb;

	/* pre-echo control */
	/* rpelev=2.0, rpelev2=16.0 */
	temp_1 = Min(ecb, Min(rpelev*nb_1[chn][b],rpelev2*nb_2[chn][b]) );
	thr[b] = Max( qthr_l[b], temp_1 ); 
	nb_2[chn][b] = nb_1[chn][b];
	nb_1[chn][b] = ecb;

	/* note: all surges in PE are because of the above pre-echo formula
	 * for temp_1.  it this is not used, PE is always around 600
	 */

	if (thr[b] < eb[b])
	  {
	    /* there's no non sound portition, because thr[b] is
	     maximum of qthr_l and temp_1 */
	    pe[chn] -= numlines_l[b] * log(thr[b] / eb[b]);
	  }
      }


#ifdef HAVEGTK
    if (gfp->gtkflag) {
      FLOAT mn,mx,ma=0,mb=0,mc=0;

      for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)
      {
        ma += energy_s[0][j];
        mb += energy_s[1][j];
        mc += energy_s[2][j];
      }
      mn = Min(ma,mb);
      mn = Min(mn,mc);
      mx = Max(ma,mb);
      mx = Max(mx,mc);

      pinfo->ers[gr_out][chn]=ers_save[chn];
      ers_save[chn]=mx/(1e-12+mn);
      pinfo->pe[gr_out][chn]=pe_save[chn];
      pe_save[chn]=pe[chn];
    }
#endif
    
    /*************************************************************** 
     * determine the block type (window type) based on L & R channels
     * 
     ***************************************************************/
    if (chn<2) {
      if (gfp->no_short_blocks){
	uselongblock[chn]=1;
      } else {
	/* tuned for t1.wav.  doesnt effect most other samples */
	if (pe[chn] > 3000) {
	  uselongblock[chn]=0;
	} else { 
	  FLOAT mn,mx,ma=0,mb=0,mc=0;
	
	  for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)
	  {
	      ma += energy_s[0][j];
	      mb += energy_s[1][j];
	      mc += energy_s[2][j];
	  }
	  mn = Min(ma,mb);
	  mn = Min(mn,mc);
	  mx = Max(ma,mb);
	  mx = Max(mx,mc);

	  uselongblock[chn] = 1;
	  
	  if ( mx > 30*mn ) 
	  {/* big surge of energy - always use short blocks */
	    uselongblock[chn] = 0;
	  } 
	  else if ((mx > 10*mn) && (pe[chn] > 1000))
	  {/* medium surge, medium pe - use short blocks */
	    uselongblock[chn] = 0;
	  }
	} 
      }
    }



    /*************************************************************** 
     * compute masking thresholds for both short and long blocks
     ***************************************************************/
    /* longblock threshold calculation (part 2) */
    for ( sb = 0; sb < SBPSY_l; sb++ )
      {
	FLOAT8 enn = w1_l[sb] * eb[bu_l[sb]] + w2_l[sb] * eb[bo_l[sb]];
	FLOAT8 thmm = w1_l[sb] *thr[bu_l[sb]] + w2_l[sb] * thr[bo_l[sb]];
	for ( b = bu_l[sb]+1; b < bo_l[sb]; b++ )
	  {
	    enn  += eb[b];
	    thmm += thr[b];
	  }
	en[chn].l[sb] = enn;
	thm[chn].l[sb] = thmm;
      }
    
    
    /* threshold calculation for short blocks */
    for ( sblock = 0; sblock < 3; sblock++ )
      {
	j = 0;
	for ( b = 0; b < npart_s_orig; b++ )
	  {
	    int i;
	    FLOAT ecb = energy_s[sblock][j++];
	    for (i = numlines_s[b]; i > 0; i--)
	      {
		ecb += energy_s[sblock][j++];
	      }
	    eb[b] = ecb;
	  }

	for ( b = 0; b < npart_s; b++ )
	  {
	    FLOAT8 ecb = 0;
	    for ( k = s3ind_s[b][0]; k <= s3ind_s[b][1]; k++ )
	      {
		ecb += s3_s[b][k] * eb[k];
	      }
	    thr[b] = Max (qthr_s[b], ecb);
	  }

	for ( sb = 0; sb < SBPSY_s; sb++ )
	  {
	    FLOAT8 enn  = w1_s[sb] * eb[bu_s[sb]] + w2_s[sb] * eb[bo_s[sb]];
	    FLOAT8 thmm = w1_s[sb] *thr[bu_s[sb]] + w2_s[sb] * thr[bo_s[sb]];
	    for ( b = bu_s[sb]+1; b < bo_s[sb]; b++ )
	      {
		enn  += eb[b];
		thmm += thr[b];
	      }
	    en[chn].s[sb][sblock] = enn;
	    thm[chn].s[sb][sblock] = thmm;
	  }
      }
  } /* end loop over chn */


  /* compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper */
  if ( numchn==4 /* mid/side and r/l */) {
    FLOAT8 rside,rmid,mld;
    int chmid=2,chside=3; 
    
    for ( sb = 0; sb < SBPSY_l; sb++ ) {
      /* use this fix if L & R masking differs by 2db or less */
      /* if db = 10*log10(x2/x1) < 2 */
      /* if (x2 < 1.58*x1) { */
      if (thm[0].l[sb] <= 1.58*thm[1].l[sb]
	  && thm[1].l[sb] <= 1.58*thm[0].l[sb]) {

	mld = mld_l[sb]*en[chside].l[sb];
	rmid = Max(thm[chmid].l[sb], Min(thm[chside].l[sb],mld));

	mld = mld_l[sb]*en[chmid].l[sb];
	rside = Max(thm[chside].l[sb],Min(thm[chmid].l[sb],mld));

	thm[chmid].l[sb]=rmid;
	thm[chside].l[sb]=rside;
      }
    }
    for ( sb = 0; sb < SBPSY_s; sb++ ) {
      for ( sblock = 0; sblock < 3; sblock++ ) {
	if (thm[0].s[sb][sblock] <= 1.58*thm[1].s[sb][sblock]
	    && thm[1].s[sb][sblock] <= 1.58*thm[0].s[sb][sblock]) {

	  mld = mld_s[sb]*en[chside].s[sb][sblock];
	  rmid = Max(thm[chmid].s[sb][sblock],Min(thm[chside].s[sb][sblock],mld));

	  mld = mld_s[sb]*en[chmid].s[sb][sblock];
	  rside = Max(thm[chside].s[sb][sblock],Min(thm[chmid].s[sb][sblock],mld));

	  thm[chmid].s[sb][sblock]=rmid;
	  thm[chside].s[sb][sblock]=rside;
	}
      }
    }
  }


  

  
  
  if (gfp->mode == MPG_MD_JOINT_STEREO)  {
    /* determin ms_ratio from masking thresholds*/
    /* use ms_stereo (ms_ratio < .35) if average thresh. diff < 5 db */
    FLOAT8 db,x1,x2,sidetot=0,tot=0;
    for (sb= SBPSY_l/4 ; sb< SBPSY_l; sb ++ ) {
      x1 = Min(thm[0].l[sb],thm[1].l[sb]);
      x2 = Max(thm[0].l[sb],thm[1].l[sb]);
      /* thresholds difference in db */
      if (x2 >= 1000*x1)  db=3;
      else db = log10(x2/x1);  
      /*  printf("db = %f %e %e  \n",db,thm[0].l[sb],thm[1].l[sb]);*/
      sidetot += db;
      tot++;
    }
    ms_ratio_l= (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */
    ms_ratio_l = Min(ms_ratio_l,0.5);
    
    sidetot=0; tot=0;
    for ( sblock = 0; sblock < 3; sblock++ )
      for ( sb = SBPSY_s/4; sb < SBPSY_s; sb++ ) {
	x1 = Min(thm[0].s[sb][sblock],thm[1].s[sb][sblock]);
	x2 = Max(thm[0].s[sb][sblock],thm[1].s[sb][sblock]);
	/* thresholds difference in db */
	if (x2 >= 1000*x1)  db=3;
	else db = log10(x2/x1);  
	sidetot += db;
	tot++;
      }
    ms_ratio_s = (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */
    ms_ratio_s = Min(ms_ratio_s,.5);
  }

  /*************************************************************** 
   * determin final block type
   ***************************************************************/

  for (chn=0; chn<gfp->stereo; chn++) {
    blocktype[chn] = NORM_TYPE;
  }


  if (gfp->stereo==2) {
    if (!gfp->allow_diff_short || gfp->mode==MPG_MD_JOINT_STEREO) {
      /* force both channels to use the same block type */
      /* this is necessary if the frame is to be encoded in ms_stereo.  */
      /* But even without ms_stereo, FhG  does this */
      int bothlong= (uselongblock[0] && uselongblock[1]);
      if (!bothlong) {
	uselongblock[0]=0;
	uselongblock[1]=0;
      }
    }
  }

  
  
  /* update the blocktype of the previous granule, since it depends on what
   * happend in this granule */
  for (chn=0; chn<gfp->stereo; chn++) {
    if ( uselongblock[chn])
      {				/* no attack : use long blocks */
	switch( blocktype_old[chn] ) 
	  {
	  case NORM_TYPE:
	  case STOP_TYPE:
	    blocktype[chn] = NORM_TYPE;
	    break;
	  case SHORT_TYPE:
	    blocktype[chn] = STOP_TYPE; 
	    break;
	  case START_TYPE:
	    fprintf( stderr, "Error in block selecting\n" );
	    abort();
	    break; /* problem */
	  }
      } else   {
	/* attack : use short blocks */
	blocktype[chn] = SHORT_TYPE;
	if ( blocktype_old[chn] == NORM_TYPE ) {
	  blocktype_old[chn] = START_TYPE;
	}
	if ( blocktype_old[chn] == STOP_TYPE ) {
	  blocktype_old[chn] = SHORT_TYPE ;
	}
      }
    
    blocktype_d[chn] = blocktype_old[chn];  /* value returned to calling program */
    blocktype_old[chn] = blocktype[chn];    /* save for next call to l3psy_anal */
  }
  
  if (blocktype_d[0]==2) 
    *ms_ratio = ms_ratio_s_old;
  else
    *ms_ratio = ms_ratio_l_old;

  ms_ratio_s_old = ms_ratio_s;
  ms_ratio_l_old = ms_ratio_l;

  /* we dont know the block type of this frame yet - assume long */
  *ms_ratio_next = ms_ratio_l;



  /*********************************************************************/
  /* compute side_energy / (side+mid)_energy */
  /* 0 = no energy in side channel */
  /* .5 = half of total energy in side channel */
  /*********************************************************************/
  if (numchn==4)  {
    FLOAT tmp = tot_ener[3]+tot_ener[2];
    *ms_ener_ratio = ms_ener_ratio_old;
    ms_ener_ratio_old=0;
    if (tmp>0) ms_ener_ratio_old=tot_ener[3]/tmp;
  } else
    /* we didn't compute ms_ener_ratios */
    *ms_ener_ratio = 0;
 
}
  bool
  CGPerturbationHandler::PerturbForSingularity(
    Number& delta_x, Number& delta_s,
    Number& delta_c, Number& delta_d)
  {
    DBG_START_METH("CGPerturbationHandler::PerturbForSingularity",
                   dbg_verbosity);

    bool retval;

    // Check for structural degeneracy
    if (hess_degenerate_ == NOT_YET_DETERMINED ||
        jac_degenerate_ == NOT_YET_DETERMINED) {
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "Degeneracy test for hess_degenerate_ = %d and jac_degenerate_ = %d\n       test_status_ = %d\n",
                     hess_degenerate_, jac_degenerate_, test_status_);
      switch (test_status_) {
      case TEST_DELTA_C_EQ_0_DELTA_X_EQ_0:
        DBG_ASSERT(delta_x_curr_ == 0. && delta_c_curr_ == 0.);
        // in this case we haven't tried anything for this matrix yet
        if (jac_degenerate_ == NOT_YET_DETERMINED) {
          delta_d_curr_ = delta_c_curr_ = delta_cd();
          test_status_ = TEST_DELTA_C_GT_0_DELTA_X_EQ_0;
        }
        else {
          DBG_ASSERT(hess_degenerate_ == NOT_YET_DETERMINED);
          retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                                delta_c, delta_d);
          if (!retval) {
            return false;
          }
          DBG_ASSERT(delta_c == 0. && delta_d == 0.);
          test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0;
        }
        break;
      case TEST_DELTA_C_GT_0_DELTA_X_EQ_0:
        DBG_ASSERT(delta_x_curr_ == 0. && delta_c_curr_ > 0.);
        DBG_ASSERT(jac_degenerate_ == NOT_YET_DETERMINED);
        //if (!perturb_always_cd_) {
        delta_d_curr_ = delta_c_curr_ =
                          Max(delta_cd(), CGPenCq().curr_cg_pert_fact());
        //delta_d_curr_ = delta_c_curr_ =
        //                 Max(delta_cd(), CGPenCq().curr_cg_pert_fact());
        if (delta_d_curr_ < delta_cd()) {
          test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0;
        }
        else {
          test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0;
        }
        retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                              delta_c, delta_d);
        if (!retval) {
          return false;
        }
        /* DBG_ASSERT(delta_c == 0. && delta_d == 0.); */
        test_status_ = TEST_DELTA_C_EQ_0_DELTA_X_GT_0;
        //}
        /*
        else {
          retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                                delta_c, delta_d);
          if (!retval) {
            return false;
          }
          DBG_ASSERT(delta_c > 0. && delta_d > 0.);
          test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0;
        }*/
        break;
      case TEST_DELTA_C_EQ_0_DELTA_X_GT_0:
        DBG_ASSERT(delta_x_curr_ > 0. && delta_c_curr_ == 0.);
        delta_d_curr_ = delta_c_curr_ = Max(delta_cd(), CGPenCq().curr_cg_pert_fact());
        //delta_d_curr_ = delta_c_curr_ = CGPenCq().curr_cg_pert_fact();
        retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                              delta_c, delta_d);
        if (!retval) {
          return false;
        }
        test_status_ = TEST_DELTA_C_GT_0_DELTA_X_GT_0;
        break;
      case TEST_DELTA_C_GT_0_DELTA_X_GT_0:
        retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                              delta_c, delta_d);
        if (!retval) {
          return false;
        }
        break;
      case NO_TEST:
        DBG_ASSERT(false && "we should not get here.");
      }
    }
    else {
      if (delta_c_curr_ > 0. || get_deltas_for_wrong_inertia_called_) {
        // If we already used a perturbation for the constraints, we do
        // the same thing as if we were encountering negative curvature
        retval = get_deltas_for_wrong_inertia(delta_x, delta_s,
                                              delta_c, delta_d);
        if (!retval) {
          Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                         "Can't get_deltas_for_wrong_inertia for delta_x_curr_ = %e and delta_c_curr_ = %e\n",
                         delta_x_curr_, delta_c_curr_);
          return false;
        }
      }
      else {
        // Otherwise we now perturb the lower right corner
        delta_d_curr_ = delta_c_curr_ = delta_cd();

        // ToDo - also perturb Hessian?
        IpData().Append_info_string("L");
        Number curr_inf = IpCq().curr_primal_infeasibility(NORM_2);
        if (!CGPenData().NeverTryPureNewton()
            && curr_inf > mult_diverg_feasibility_tol_) {
          Number penalty = CGPenCq().compute_curr_cg_penalty_scale();
          penalty = Min(penalty_max_, Max(penalty,
                                          CGPenData().curr_kkt_penalty()));
          CGPenData().Set_kkt_penalty(penalty);
          Number mach_pro = std::numeric_limits<Number>::epsilon();
          delta_d_curr_ = delta_c_curr_ =
                            Max(1e3*mach_pro,Max(CGPenCq().curr_cg_pert_fact(),delta_cd()));
          IpData().Append_info_string("u");
        }
      }
    }

    delta_x = delta_x_curr_;
    delta_s = delta_s_curr_;
    delta_c = delta_c_curr_;
    delta_d = delta_d_curr_;

    IpData().Set_info_regu_x(delta_x);

    return true;
  }
Example #20
0
   which can be found in the LICENSE file in the root directory, or at 
   http://opensource.org/licenses/BSD-2-Clause
*/
#pragma once
#ifndef EL_HESSENBERG_LUNB_HPP
#define EL_HESSENBERG_LUNB_HPP

namespace El {
namespace hessenberg {

template<typename F>
inline void LUnb( Matrix<F>& A, Matrix<F>& t )
{
    DEBUG_ONLY(CallStackEntry cse("hessenberg::LUnb"))
    const Int n = A.Height();
    const Int tHeight = Max(n-1,0);
    t.Resize( tHeight, 1 );

    Matrix<F> z1, z21;

    for( Int k=0; k<n-1; ++k )
    {
        auto a12      = ViewRange( A, k,   k+1, k+1, n   );
        auto alpha12L = ViewRange( A, k,   k+1, k+1, k+2 );
        auto a12R     = ViewRange( A, k,   k+2, k+1, n   );
        auto A22      = ViewRange( A, k+1, k+1, n,   n   );
        auto A2       = ViewRange( A, k+1, 0,   n,   n   );

        // Find tau and v such that
        //  |alpha12L a12R| /I - tauP | 1   | | 1 conj(v) |\ = |beta 0|
        //                  \         | v^T |              /
Example #21
0
const FontFace* Font::GetFaceTTF(int pointSize)
{
    // Create & initialize FreeType library if it does not exist yet
    FreeTypeLibrary* freeType = GetSubsystem<FreeTypeLibrary>();
    if (!freeType)
        context_->RegisterSubsystem(freeType = new FreeTypeLibrary(context_));

    FT_Face face;
    FT_Error error;
    FT_Library library = freeType->GetLibrary();

    if (pointSize <= 0)
    {
        LOGERROR("Zero or negative point size");
        return 0;
    }

    if (!fontDataSize_)
    {
        LOGERROR("Font not loaded");
        return 0;
    }

    error = FT_New_Memory_Face(library, &fontData_[0], fontDataSize_, 0, &face);
    if (error)
    {
        LOGERROR("Could not create font face");
        return 0;
    }
    error = FT_Set_Char_Size(face, 0, pointSize * 64, FONT_DPI, FONT_DPI);
    if (error)
    {
        FT_Done_Face(face);
        LOGERROR("Could not set font point size " + String(pointSize));
        return 0;
    }

    SharedPtr<FontFace> newFace(new FontFace());

    FT_GlyphSlot slot = face->glyph;
    unsigned numGlyphs = 0;

    // Build glyph mapping
    FT_UInt glyphIndex;
    FT_ULong charCode = FT_Get_First_Char(face, &glyphIndex);
    while (glyphIndex != 0)
    {
        numGlyphs = Max((int)glyphIndex + 1, (int)numGlyphs);
        newFace->glyphMapping_[charCode] = glyphIndex;
        charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
    }

    LOGDEBUG("Font face has " + String(numGlyphs) + " glyphs");

    // Load each of the glyphs to see the sizes & store other information
    int maxHeight = 0;
    FT_Pos ascender = face->size->metrics.ascender;

    newFace->glyphs_.Reserve(numGlyphs);

    for (unsigned i = 0; i < numGlyphs; ++i)
    {
        FontGlyph newGlyph;

        error = FT_Load_Glyph(face, i, FT_LOAD_DEFAULT);
        if (!error)
        {
            // Note: position within texture will be filled later
            newGlyph.width_ = (short)((slot->metrics.width) >> 6);
            newGlyph.height_ = (short)((slot->metrics.height) >> 6);
            newGlyph.offsetX_ = (short)((slot->metrics.horiBearingX) >> 6);
            newGlyph.offsetY_ = (short)((ascender - slot->metrics.horiBearingY) >> 6);
            newGlyph.advanceX_ = (short)((slot->metrics.horiAdvance) >> 6);

            maxHeight = Max(maxHeight, newGlyph.height_);
        }
        else
        {
Example #22
0
void UIHierarchy::DragInput(UIEvent *input)
{
    switch (input->phase)
    {
    case UIEvent::PHASE_BEGAN:
    {
        lockTouch = true;
        mainTouch = input->tid;

        if(InputSystem::Instance()->GetKeyboard()->IsKeyPressed(DVKEY_CTRL))
        {
            dragMode = DRAG_CHANGE_PARENT;
        }
        if(InputSystem::Instance()->GetKeyboard()->IsKeyPressed(DVKEY_SHIFT))
        {
            dragMode = DRAG_CHANGE_ORDER;
        }

        UIHierarchyCell *draggedCell = FindVisibleCellForPoint(input->point);
        if(draggedCell && draggedCell->GetNode())
        {
            draggedData = draggedCell->GetNode()->GetUserNode();
        }
        break;
    }
    case UIEvent::PHASE_DRAG:
    {
        if(cellUnderDrag)
        {
            cellUnderDrag->SetDebugDraw(false, false);
        }

        cellUnderDrag = FindVisibleCellForPoint(input->point);

        if(cellUnderDrag)
        {
            cellUnderDrag->SetDebugDraw(true, false);
        }

        Vector2 topOffset = input->point - GetPosition(true);
        Vector2 bottomOffset = input->point - (GetPosition(true) + GetSize());

        if(topOffset.y < 0)
        {
            float32 scrollPos = scroll->GetPosition();
            if(scrollPos < 0)
            {
                scroll->SetPosition(scrollPos - topOffset.y);
            }
        }
        else if(0 < bottomOffset.y)
        {
            float32 scrollPos = scroll->GetPosition();
            float32 viewSize = scroll->GetViewSize();
            float32 elementsSize = scroll->GetElementSize();

            if(scrollPos + viewSize < elementsSize)
            {
                float32 newPos = scrollPos - bottomOffset.y;
                newPos = Max(newPos, viewSize-elementsSize);

                scroll->SetPosition(newPos);
            }
        }
        break;
    }
    case UIEvent::PHASE_ENDED:
    {
        if(draggedData)
        {
            UIHierarchyCell *targetCell = FindVisibleCellForPoint(input->point);
            void *targetData = NULL;
            if(targetCell && targetCell->GetNode())
            {
                targetData = targetCell->GetNode()->GetUserNode();
            }

            if(delegate && (draggedData != targetData))
            {
                delegate->DragAndDrop(draggedData, targetData, dragMode);
            }
        }
        //break; not needed!
    }
    case UIEvent::PHASE_CANCELLED:
    {
        lockTouch = false;
        mainTouch = 0;

        dragMode = DRAG_NONE;

        if(cellUnderDrag)
        {
            cellUnderDrag->SetDebugDraw(false, false);
            cellUnderDrag = NULL;
        }

        draggedData = NULL;

        break;
    }

    default:
    {
        break;
    }
    }
}
Example #23
0
void Image::ResizeToSquare()
{
    uint32 newImageSize = Max(width, height);
    ResizeCanvas(newImageSize, newImageSize);
}
Example #24
0
//------------------------------------------------------------------------
void WINAPI ReadCfg(void)
{
	char str[ FAR_MAX_NAME ],*m;
	int  val,n;
#define GCMD( fnm,nm,v ) FP_GetRegKey( fnm,Opt.v,nm,ARRAYSIZE(Opt.v) ); if (TrimLen(Opt.v) == 0) strcpy( Opt.v,nm );
	Opt.AddToDisksMenu     = FP_GetRegKey("AddToDisksMenu",     1);
	Opt.AddToPluginsMenu   = FP_GetRegKey("AddToPluginsMenu",   1);
	Opt.DisksMenuDigit     = FP_GetRegKey("DisksMenuDigit",     2);
	Opt.ReadDescriptions   = FP_GetRegKey("ReadDescriptions",   0);
	Opt.UploadLowCase      = FP_GetRegKey("UploadLowCase",      0);
	Opt.ShowUploadDialog   = FP_GetRegKey("ShowUploadDialog",   1);
	Opt.ResumeDefault      = FP_GetRegKey("ResumeDefault",      0);
	Opt.UpdateDescriptions = FP_GetRegKey("UpdateDescriptions", 0);
	Opt.PassiveMode        = FP_GetRegKey("PassiveMode",        0);
	FP_GetRegKey("CharTable",        Opt.Table,NULL,ARRAYSIZE(Opt.Table));
	FP_GetRegKey("DescriptionNames", Opt.DescriptionNames,"00_index.txt,0index,0index.txt",ARRAYSIZE(Opt.DescriptionNames));
	FP_GetRegKey("Firewall",Opt.Firewall,NULL,ARRAYSIZE(Opt.Firewall));
	FP_GetRegKey("DefaultPassword", (BYTE *)str,(BYTE *)NULL,ARRAYSIZE(str));
	DecryptPassword((BYTE*)str,Opt.DefaultPassword);
//JM
	Opt.CmdLength          =       Max(5,Min(FP_ConHeight()-5,FP_GetRegKey("CmdLength",7)));
	Opt.CmdLine            =       Max(10,Min(FP_ConWidth()-9,FP_GetRegKey("CmdLine",70)));
	Opt.IOBuffSize         =       Max(FTR_MINBUFFSIZE,(DWORD)FP_GetRegKey("IOBuffSize",512));
	Opt.dDelimit           =       FP_GetRegKey("DigitDelimit",       TRUE);
	Opt.dDelimiter         = (char)FP_GetRegKey("DigitDelimiter",     0);
	Opt.WaitTimeout        =       FP_GetRegKey("WaitTimeout",        30);
	Opt.AskAbort           =       FP_GetRegKey("AskAbort",           TRUE);
	Opt.WaitIdle           =       FP_GetRegKey("WaitIdle",           1);
	Opt.CmdLogLimit        =       FP_GetRegKey("CmdLogLimit",        100);
	Opt.ShowIdle           =       FP_GetRegKey("ShowIdle",           TRUE);
	Opt.TimeoutRetry       =       FP_GetRegKey("TimeoutRetry",       FALSE);
	Opt.RetryCount         =       FP_GetRegKey("RetryCount",         0);
	Opt.LogOutput          =       FP_GetRegKey("LogOutput",          FALSE);
	Opt._ShowPassword      =       FP_GetRegKey("ShowPassword",       FALSE);
	Opt.IdleColor          =       FP_GetRegKey("IdleColor",          FAR_COLOR(fccCYAN,fccBLUE));
	Opt.IdleMode           =       FP_GetRegKey("IdleMode",           IDLE_CONSOLE);
	Opt.LongBeepTimeout    =       FP_GetRegKey("BeepTimeout",        30);
	Opt.KeepAlive          =       FP_GetRegKey("KeepAlive",          60);
	Opt.IdleShowPeriod     =       FP_GetRegKey("IdleShowPeriod",     700);
	Opt.IdleStartPeriod    =       FP_GetRegKey("IdleStartPeriod",    4000);
	Opt.AskLoginFail       =       FP_GetRegKey("AskLoginFail",       TRUE);
	Opt.ExtCmdView         =       FP_GetRegKey("ExtCmdView",         TRUE);
	Opt.AutoAnonymous      =       FP_GetRegKey("AutoAnonymous",      TRUE);
	Opt.CloseDots          =       FP_GetRegKey("CloseDots",          TRUE);
	Opt.QuoteClipboardNames=       FP_GetRegKey("QuoteClipboardNames",TRUE);
	Opt.SetHiddenOnAbort   =       FP_GetRegKey("SetHiddenOnAbort",   FALSE);
	Opt.PwdSecurity        =       FP_GetRegKey("PwdSecurity",        0);
	Opt.WaitCounter        =       FP_GetRegKey("WaitCounter",        0);
	Opt.RetryTimeout       =       FP_GetRegKey("RetryTimeout",       10);
	Opt.DoNotExpandErrors  =       FP_GetRegKey("DoNotExpandErrors",  FALSE);
	Opt.TruncateLogFile    =       FP_GetRegKey("TruncateLogFile",    FALSE);
	Opt.ServerType         =       FP_GetRegKey("ServerType",         FTP_TYPE_DETECT);
	Opt.UseBackups         =       FP_GetRegKey("UseBackups",         TRUE);
	Opt.ProcessCmd         =       FP_GetRegKey("ProcessCmd",         TRUE);
	Opt.FFDup              =       FP_GetRegKey("FFDup",              FALSE);
	Opt.UndupFF            =       FP_GetRegKey("UndupFF",            FALSE);
	Opt.ShowSilentProgress =       FP_GetRegKey("ShowSilentProgress", FALSE);
	FP_GetRegKey("InvalidSymbols",     Opt.InvalidSymbols,   "<>|?*\"", ARRAYSIZE(Opt.InvalidSymbols));
	FP_GetRegKey("CorrectedSymbols",   Opt.CorrectedSymbols, "()!__\'", ARRAYSIZE(Opt.CorrectedSymbols));

	for(n = 0; Opt.InvalidSymbols[n] && Opt.CorrectedSymbols[n]; n++);

	Opt.InvalidSymbols[n]   = 0;
	Opt.CorrectedSymbols[n] = 0;
	Opt.PluginColumnMode   = (int)FP_GetRegKey("PluginColumnMode", MAX_DWORD);

	if(Opt.PluginColumnMode < 0 || Opt.PluginColumnMode >= 10)
		Opt.PluginColumnMode = -1;

	FP_GetRegKey("CmdLogFile", Opt.CmdLogFile,"",ARRAYSIZE(Opt.CmdLogFile));
//Queue
	Opt.RestoreState           = FP_GetRegKey("QueueRestoreState",    TRUE);
	Opt.RemoveCompleted        = FP_GetRegKey("QueueRemoveCompleted", TRUE);
	Opt.sli.AddPrefix          = FP_GetRegKey("AddPrefix",          TRUE);
	Opt.sli.AddPasswordAndUser = FP_GetRegKey("AddPasswordAndUser", TRUE);
	Opt.sli.Quote              = FP_GetRegKey("Quote",              TRUE);
	Opt.sli.Size               = FP_GetRegKey("Size",               TRUE);
	Opt.sli.RightBound         = FP_GetRegKey("RightBound",         80);
	Opt.sli.ListType           = (sliTypes)FP_GetRegKey("ListType",           sltUrlList);
//Formats
	GCMD("ServerDateFormat", "%*s %04d%02d%02d%02d%02d%02d", fmtDateFormat)
//Months
	static const char *Months[12]= { "Jan","Feb","Mar","Apr","May","Jun",
	                                 "Jul","Aug","Sep","Oct","Nov","Dec"
	                               };

	for(n = 0; n < 12; n++)
	{
		FP_GetRegKey(Months[n], str, Months[n], ARRAYSIZE(str));

		while((m=strpbrk(str,"\n\r\b")) != NULL) *m = 0;

		if(!str[0])
			strcpy(str,Months[n]);

		Log(("month %d [%s]=[%s]",n,Opt.Months[n],str));

		if(Opt.Months[n])
			free(Opt.Months[n]);

		Opt.Months[n] = strdup(str);
	}

//CMD`s
	GCMD("xcmdPUT",  "STOR", cmdPut)
	GCMD("xcmdAPPE", "APPE", cmdAppe)
	GCMD("xcmdSTOR", "STOR", cmdStor)
	GCMD("xcmdSTOU", "STOU", cmdPutUniq)
	GCMD("xcmdPASV", "PASV", cmdPasv)
	GCMD("xcmdPORT", "PORT", cmdPort)
	GCMD("xcmdMDTM", "MDTM", cmdMDTM)
	GCMD("xcmdRETR", "RETR", cmdRetr)
	GCMD("xcmdREST", "REST", cmdRest)
	GCMD("xcmdALLO", "ALLO", cmdAllo)
	GCMD("xcmdCWD",  "CWD",  cmdCwd)
	GCMD("xcmdXCWD", "XCWD", cmdXCwd)
	GCMD("xcmdDELE", "DELE", cmdDel)
	GCMD("xcmdRNFR", "RNFR", cmdRen)
	GCMD("xcmdRNTO", "RNTO", cmdRenTo)
	GCMD("xcmdLIST", "LIST", cmdList)
	GCMD("xcmdNLIST","NLIST",cmdNList)
	GCMD("xcmdUSER", "USER", cmdUser)
	GCMD("xcmdPASS", "PASS", cmdPass)
	GCMD("xcmdACCT", "ACCT", cmdAcct)
	GCMD("xcmdPWD",  "PWD",  cmdPwd)
	GCMD("xcmdXPWD", "XPWD", cmdXPwd)
	GCMD("xcmdMKD",  "MKD",  cmdMkd)
	GCMD("xcmdXMKD", "XMKD", cmdXMkd)
	GCMD("xcmdRMD",  "RMD",  cmdRmd)
	GCMD("xcmdXRMD", "XRMD", cmdXRmd)
	GCMD("xcmdSITE", "SITE", cmdSite)
	GCMD("xcmdCHMOD","CHMOD",cmdChmod)
	GCMD("xcmdUMASK","UMASK",cmdUmask)
	GCMD("xcmdIDLE", "IDLE", cmdIdle)
	GCMD("xcmdHELP", "HELP", cmdHelp)
	GCMD("xcmdQUIT", "QUIT", cmdQuit)
	GCMD("xcmdCDUP", "CDUP", cmdCDUp)
	GCMD("xcmdXCUP", "XCUP", cmdXCDUp)
	GCMD("xcmdSYST", "SYST", cmdSyst)
	GCMD("xcmdSIZE", "SIZE", cmdSize)
	GCMD("xcmdSTAT", "STAT", cmdStat)
//ProcessColor
	val = (int)FP_Info->AdvControl(FP_Info->ModuleNumber,ACTL_GETCOLOR,(void*)COL_DIALOGBOX);
	Opt.ProcessColor = FP_GetRegKey("ProcessColor",val);

//dDelimit && dDelimiter
	if(Opt.dDelimit && Opt.dDelimiter == 0)
	{
		if(GetLocaleInfo(GetThreadLocale(),LOCALE_STHOUSAND,str,ARRAYSIZE(str)))
		{
			CharToOemBuff(str,str,2);
			Opt.dDelimiter = str[0];
		}
		else
			Opt.dDelimiter = '.';
	}
}
Example #25
0
void Text::UpdateText(bool onResize)
{
    rowWidths_.Clear();
    printText_.Clear();

    if (font_)
    {
        FontFace* face = font_->GetFace(fontSize_);
        if (!face)
            return;

        rowHeight_ = face->GetRowHeight();

        int width = 0;
        int height = 0;
        int rowWidth = 0;
        int rowHeight = (int)(rowSpacing_ * rowHeight_);

        // First see if the text must be split up
        if (!wordWrap_)
        {
            printText_ = unicodeText_;
            printToText_.Resize(printText_.Size());
            for (unsigned i = 0; i < printText_.Size(); ++i)
                printToText_[i] = i;
        }
        else
        {
            int maxWidth = GetWidth();
            unsigned nextBreak = 0;
            unsigned lineStart = 0;
            printToText_.Clear();

            for (unsigned i = 0; i < unicodeText_.Size(); ++i)
            {
                unsigned j;
                unsigned c = unicodeText_[i];

                if (c != '\n')
                {
                    bool ok = true;

                    if (nextBreak <= i)
                    {
                        int futureRowWidth = rowWidth;
                        for (j = i; j < unicodeText_.Size(); ++j)
                        {
                            unsigned d = unicodeText_[j];
                            if (d == ' ' || d == '\n')
                            {
                                nextBreak = j;
                                break;
                            }
                            const FontGlyph* glyph = face->GetGlyph(d);
                            if (glyph)
                            {
                                futureRowWidth += glyph->advanceX_;
                                if (j < unicodeText_.Size() - 1)
                                    futureRowWidth += face->GetKerning(d, unicodeText_[j + 1]);
                            }
                            if (d == '-' && futureRowWidth <= maxWidth)
                            {
                                nextBreak = j + 1;
                                break;
                            }
                            if (futureRowWidth > maxWidth)
                            {
                                ok = false;
                                break;
                            }
                        }
                    }

                    if (!ok)
                    {
                        // If did not find any breaks on the line, copy until j, or at least 1 char, to prevent infinite loop
                        if (nextBreak == lineStart)
                        {
                            while (i < j)
                            {
                                printText_.Push(unicodeText_[i]);
                                printToText_.Push(i);
                                ++i;
                            }
                        }
                        // Eliminate spaces that have been copied before the forced break
                        while (printText_.Size() && printText_.Back() == ' ')
                        {
                            printText_.Pop();
                            printToText_.Pop();
                        }
                        printText_.Push('\n');
                        printToText_.Push((unsigned)Min((int)i, (int)unicodeText_.Size() - 1));
                        rowWidth = 0;
                        nextBreak = lineStart = i;
                    }

                    if (i < unicodeText_.Size())
                    {
                        // When copying a space, position is allowed to be over row width
                        c = unicodeText_[i];
                        const FontGlyph* glyph = face->GetGlyph(c);
                        if (glyph)
                        {
                            rowWidth += glyph->advanceX_;
                            if (i < unicodeText_.Size() - 1)
                                rowWidth += face->GetKerning(c, unicodeText_[i + 1]);
                        }
                        if (rowWidth <= maxWidth)
                        {
                            printText_.Push(c);
                            printToText_.Push(i);
                        }
                    }
                }
                else
                {
                    printText_.Push('\n');
                    printToText_.Push((unsigned)Min((int)i, (int)unicodeText_.Size() - 1));
                    rowWidth = 0;
                    nextBreak = lineStart = i;
                }
            }
        }

        rowWidth = 0;

        for (unsigned i = 0; i < printText_.Size(); ++i)
        {
            unsigned c = printText_[i];

            if (c != '\n')
            {
                const FontGlyph* glyph = face->GetGlyph(c);
                if (glyph)
                {
                    rowWidth += glyph->advanceX_;
                    if (i < printText_.Size() - 1)
                        rowWidth += face->GetKerning(c, printText_[i + 1]);
                }
            }
            else
            {
                width = Max(width, rowWidth);
                height += rowHeight;
                rowWidths_.Push(rowWidth);
                rowWidth = 0;
            }
        }

        if (rowWidth)
        {
            width = Max(width, rowWidth);
            height += rowHeight;
            rowWidths_.Push(rowWidth);
        }

        // Set at least one row height even if text is empty
        if (!height)
            height = rowHeight;

        // Set minimum and current size according to the text size, but respect fixed width if set
        if (!IsFixedWidth())
        {
            SetMinWidth(wordWrap_ ? 0 : width);
            SetWidth(width);
        }
        SetFixedHeight(height);

        charLocationsDirty_ = true;
    }
    else
    {
        // No font, nothing to render
        pageGlyphLocations_.Clear();
    }

    // If wordwrap is on, parent may need layout update to correct for overshoot in size. However, do not do this when the
    // update is a response to resize, as that could cause infinite recursion
    if (wordWrap_ && !onResize)
    {
        UIElement* parent = GetParent();
        if (parent && parent->GetLayoutMode() != LM_FREE)
            parent->UpdateLayout();
    }
}
Example #26
0
int WINAPI Config(void)
{
	InitDialogItem InitItems[]=
	{
		{DI_DOUBLEBOX, 3, 1,72,21, 0,0,0,0, FMSG(MConfigTitle)},
		{DI_CHECKBOX,5, 2,0,0,0, 0,0,0,  FMSG(MConfigAddToDisksMenu)},      //Add to Disks menu
		{DI_FIXEDIT,35, 2,37, 2,0,0,0,0,NULL},
		{DI_CHECKBOX,5, 3,0,0,0, 0,0,0,  FMSG(MConfigAddToPluginsMenu)},    //Add to Plugins menu
		{DI_TEXT,9, 4,0,0,0, 0,0,0,  FMSG(MHostsMode)},                 //Hosts panel mode
		{DI_FIXEDIT,5, 4, 7, 4,0,0,0,0,NULL},
		{DI_CHECKBOX,5, 5,0,0,0,  0,0,0, FMSG(MConfigReadDiz)},             //Read descriptions
		{DI_CHECKBOX,5, 6,0,0,0, 0,0,0,  FMSG(MConfigUpdateDiz)},           //Update descriptions
		{DI_CHECKBOX,5, 7,0,0,0, 0,0,0,  FMSG(MConfigUploadLowCase)},       //Upload upper in lowercase
		{DI_CHECKBOX,5, 8,0,0,0, 0,0,0,  FMSG(MConfigUploadDialog)},        //Show upload options dialog
		{DI_CHECKBOX,5, 9,0,0,0, 0,0,0,  FMSG(MConfigDefaultResume)},       //Default button is 'Resume'
		{DI_CHECKBOX,5,10,0,0,0, 0,0,0,  FMSG(MAskAbort)},                  //Confirm abort
		{DI_CHECKBOX,5,11,0,0,0, 0,0,0,  FMSG(MShowIdle)},                  //Show idle
		{DI_BUTTON,21,11,0,0,0, 0,0,0,  FMSG(MColor)},                    //Color
		{DI_RADIOBUTTON,32,11,0,0,0,0,DIF_GROUP, 0,  FMSG(MScreen)},                   //( ) 1.Screen
		{DI_RADIOBUTTON,44,11,0,0,0,  0,0,0, FMSG(MCaption)},                  //( ) 2.Caption
		{DI_RADIOBUTTON,58,11,0,0,0,  0,0,0, FMSG(MBoth)},                     //( ) 3.Both

		{DI_CHECKBOX,40, 2,0,0,0, 0,0,0,  FMSG(MKeepAlive)},                //Keepalive packet
		{DI_EDIT,67, 2,70, 2,0,0,0,0,NULL},
		{DI_TEXT,71, 2,0,0,0, 0,0,0,  FMSG(MSec)},                      //s
		{DI_CHECKBOX,40, 3,0,0,0, 0,0,0,  FMSG(MAutoRetry)},                //AutoRetry
		{DI_EDIT,67, 3,70, 3,0,0,0,0,NULL},
		{DI_CHECKBOX,40, 4,0,0,0, 0,0,0,  FMSG(MLongOp)},                   //Long operation beep
		{DI_EDIT,67, 4,70, 4,0,0,0,0,NULL},
		{DI_TEXT,71, 4,0,0,0,  0,0,0, FMSG(MSec)},                      //s
		{DI_TEXT,40, 5,0,0,0, 0,0,0,  FMSG(MWaitTimeout)},              //Server reply timeout (s)
		{DI_EDIT,67, 5,70, 5,0,0,0,0,NULL},
		{DI_CHECKBOX,40, 6,0,0,0, 0,0,0,  FMSG(MDigitDelimit)},             //Digits grouping symbol
		{DI_EDIT,69, 6,70, 6,0,0,0,0,NULL},
		{DI_CHECKBOX,40, 7,0,0,0, 0,0,0,  FMSG(MExtWindow)},                //Show FTP command log
		{DI_TEXT,40, 8,0,0,0,  0,0,0, FMSG(MExtSize)},                  //Log window size
		{DI_EDIT,60, 8,63, 8,0,0,0,0,NULL},
		{DI_TEXT,64, 8,0,0,0,0,0,0,   " x "},
		{DI_EDIT,67, 8,70, 8,0,0,0,0,NULL},
		{DI_TEXT,40, 9,0,0,0,  0,0,0, FMSG(MHostIOSize)},               //I/O buffer size
		{DI_EDIT,60, 9,70, 9,0,0,0,0,NULL},
		{DI_TEXT,40,10,0,0,0,  0,0,0, FMSG(MSilentText)},               //Alert text
		{DI_BUTTON,60,10,0,0,0,0,0,0,   FMSG(MColor)},

		{DI_TEXT,5,12,5,12,0,0,DIF_BOXCOLOR|DIF_SEPARATOR,0,NULL },

		{DI_TEXT,5,13,0,0,0, 0,0,0,  FMSG(MConfigDizNames)},            //Dis names
		{DI_EDIT,5,14,70,14,0,0,0,0,NULL},
		{DI_TEXT,5,15,0,0,0, 0,0,0,  FMSG(MConfigDefPassword)},         //Def pass
		{DI_PSWEDIT,5,16,34,16,0,0,0,0,NULL},
		{DI_TEXT,5,17,0,0,0, 0,0,0,  FMSG(MConfigFirewall)},            //Firewall
		{DI_EDIT,5,18,34,18,0,0,0,0,NULL},
		{DI_TEXT,40,15,0,0,0, 0,0,0,  FMSG(MLogFilename)},              //Log filename
		{DI_EDIT,66,15,70,15,0,0,0,0,NULL},
		{DI_TEXT,71,15,0,0,0, 0,0,0,  FMSG(MKBytes)},
		{DI_EDIT,40,16,70,16,0,0,0,0,NULL},
		{DI_CHECKBOX,40,17,0,0,0,  0,0,0, FMSG(MLogDir)},                   //Log DIR contents
		{DI_CHECKBOX,40,18,0,0,0, 0,0,0,  FMSG(MConfigPassiveMode)},
		{DI_TEXT,5,19,5,19,0,0,DIF_BOXCOLOR|DIF_SEPARATOR,0,NULL },
		{DI_BUTTON,0,20,0,0,0,0,DIF_CENTERGROUP, 1,  FMSG(MOk)},
		{DI_BUTTON,0,20,0,0,0,0,DIF_CENTERGROUP, 0,  FMSG(MCancel)},
		{DI_BUTTON,0,20,0,0,0,0,DIF_CENTERGROUP, 0,  FMSG(MExtOpt)},
	};
#define CFG_ADDDISK       1
#define CFG_DIGIT         2
#define CFG_ADDPLUGINS    3
#define CFG_HOSTMODE      5
#define CFG_READDIZ       6
#define CFG_UPDDIZ        7
#define CFG_UPCASE        8
#define CFG_SHOWUP        9
#define CFG_RESDEF        10
#define CFG_ASKABORT      11
#define CFG_SHOWIDLE      12
#define CFG_IDLECOLOR     13
#define CFG_IDLE_SCREEN   14
#define CFG_IDLE_CAPTION  15
#define CFG_IDLE_BOTH     16
#define CFG_KEEPALIVE     17
#define CFG_KEEPTIME      18
#define CFG_AUTOR         20
#define CFG_AUTORTIME     21
#define CFG_LONGOP        22
#define CFG_LONGOPTIME    23
#define CFG_WAITTIMEOUT   26
#define CFG_DIGDEL        27
#define CFG_DIGCHAR       28
#define CFG_EXT           29
#define CFG_EXT_W         31
#define CFG_EXT_H         33
#define CFG_BUFFSIZE      35
#define CFG_SILENT        37
#define CFG_DESC          40
#define CFG_PASS          42
#define CFG_FIRE          44
#define CFG_LOGLIMIT      46
#define CFG_LOGFILE       48
#define CFG_LOGDIR        49
#define CFG_PASV          50
#define CFG_OK            52
#define CFG_CANCEL        53
#define CFG_EXTBTN        54
	FarDialogItem DialogItems[ARRAYSIZE(InitItems)];
	int           IdleColor    = Opt.IdleColor,
	              ProcessColor = Opt.ProcessColor;
	int           rc;
	InitDialogItems(InitItems,DialogItems,ARRAYSIZE(DialogItems));
	DialogItems[CFG_ADDDISK].Selected = Opt.AddToDisksMenu;
	sprintf(DialogItems[CFG_DIGIT].Data,"%d",Opt.DisksMenuDigit);
	DialogItems[CFG_ADDPLUGINS].Selected  = Opt.AddToPluginsMenu;
	sprintf(DialogItems[CFG_HOSTMODE].Data,"%d",Opt.PluginColumnMode);
	DialogItems[CFG_READDIZ].Selected     = Opt.ReadDescriptions;
	DialogItems[CFG_UPDDIZ].Selected      = Opt.UpdateDescriptions;
	DialogItems[CFG_UPCASE].Selected      = Opt.UploadLowCase;
	DialogItems[CFG_SHOWUP].Selected      = Opt.ShowUploadDialog;
	DialogItems[CFG_RESDEF].Selected      = Opt.ResumeDefault;
	sprintf(DialogItems[CFG_WAITTIMEOUT].Data,"%d",Opt.WaitTimeout);
	DialogItems[CFG_SHOWIDLE].Selected    = Opt.ShowIdle;
	DialogItems[CFG_IDLE_SCREEN].Selected  = Opt.IdleMode == IDLE_CONSOLE;
	DialogItems[CFG_IDLE_CAPTION].Selected = Opt.IdleMode == IDLE_CAPTION;
	DialogItems[CFG_IDLE_BOTH].Selected    = Opt.IdleMode == (IDLE_CONSOLE|IDLE_CAPTION);
	DialogItems[CFG_KEEPALIVE].Selected   = Opt.KeepAlive != 0;
	sprintf(DialogItems[CFG_KEEPTIME].Data,"%d",Opt.KeepAlive);
	DialogItems[CFG_AUTOR].Selected       = Opt.TimeoutRetry;
	sprintf(DialogItems[CFG_AUTORTIME].Data,"%d",Opt.RetryCount);
	DialogItems[CFG_LONGOP].Selected      = Opt.LongBeepTimeout != 0;
	sprintf(DialogItems[CFG_LONGOPTIME].Data,"%d",Opt.LongBeepTimeout);
	DialogItems[CFG_ASKABORT].Selected    = Opt.AskAbort;
	DialogItems[CFG_DIGDEL].Selected      = Opt.dDelimit;
	sprintf(DialogItems[CFG_DIGCHAR].Data,"%c",Opt.dDelimiter);
	DialogItems[CFG_EXT].Selected         = Opt.ExtCmdView;
	sprintf(DialogItems[CFG_EXT_W].Data,"%d",Opt.CmdLine);
	sprintf(DialogItems[CFG_EXT_H].Data,"%d",Opt.CmdLength);
	Size2Str(DialogItems[CFG_BUFFSIZE].Data,Opt.IOBuffSize);
	strcpy(DialogItems[CFG_DESC].Data,Opt.DescriptionNames);
	strcpy(DialogItems[CFG_PASS].Data,Opt.DefaultPassword);
	strcpy(DialogItems[CFG_FIRE].Data,Opt.Firewall);
	sprintf(DialogItems[CFG_LOGLIMIT].Data,"%d",Opt.CmdLogLimit);
	sprintf(DialogItems[CFG_LOGFILE].Data,"%s",Opt.CmdLogFile);
	DialogItems[CFG_LOGDIR].Selected      = Opt.LogOutput;
	DialogItems[CFG_PASV].Selected        = Opt.PassiveMode;

	do
	{
		rc = FDialog(76,23,"Config",DialogItems,ARRAYSIZE(DialogItems));

		if(rc == CFG_OK)
			break;

		if(rc == -1 || rc == CFG_CANCEL)
			return FALSE;

		if(rc == CFG_IDLECOLOR)
			IdleColor = FP_GetColorDialog(IdleColor,&ColorLangs,NULL);
		else if(rc == CFG_SILENT)
			ProcessColor = FP_GetColorDialog(ProcessColor,&ColorLangs,NULL);
		else if(rc == CFG_EXTBTN)
			ExtendedConfig();
	}
	while(true);

//Set to OPT
	Opt.IdleColor          = IdleColor;
	Opt.ProcessColor       = ProcessColor;
	Opt.AddToDisksMenu     = DialogItems[CFG_ADDDISK].Selected;
	Opt.DisksMenuDigit     = atoi(DialogItems[CFG_DIGIT].Data);
	Opt.AddToPluginsMenu   = DialogItems[CFG_ADDPLUGINS].Selected;
	Opt.PluginColumnMode   = atoi(DialogItems[CFG_HOSTMODE].Data);
	Opt.ReadDescriptions   = DialogItems[CFG_READDIZ].Selected;
	Opt.UpdateDescriptions = DialogItems[CFG_UPDDIZ].Selected;
	Opt.UploadLowCase      = DialogItems[CFG_UPCASE].Selected;
	Opt.ShowUploadDialog   = DialogItems[CFG_SHOWUP].Selected;
	Opt.ResumeDefault      = DialogItems[CFG_RESDEF].Selected;
	Opt.WaitTimeout        = atoi(DialogItems[CFG_WAITTIMEOUT].Data);
	Opt.ShowIdle           = DialogItems[CFG_SHOWIDLE].Selected;

	if(DialogItems[CFG_IDLE_SCREEN].Selected)  Opt.IdleMode = IDLE_CONSOLE;
	else if(DialogItems[CFG_IDLE_CAPTION].Selected) Opt.IdleMode = IDLE_CAPTION;
	else
		Opt.IdleMode = IDLE_CONSOLE | IDLE_CAPTION;

	if(DialogItems[CFG_KEEPALIVE].Selected)
		Opt.KeepAlive = atoi(DialogItems[CFG_KEEPTIME].Data);
	else
		Opt.KeepAlive = 0;

	Opt.TimeoutRetry = DialogItems[CFG_AUTOR].Selected;
	Opt.RetryCount   = atoi(DialogItems[CFG_AUTORTIME].Data);

	if(DialogItems[CFG_LONGOP].Selected)
		Opt.LongBeepTimeout = atoi(DialogItems[CFG_LONGOPTIME].Data);
	else
		Opt.LongBeepTimeout = 0;

	Opt.AskAbort           = DialogItems[CFG_ASKABORT].Selected;
	Opt.dDelimit           = DialogItems[CFG_DIGDEL].Selected;
	Opt.dDelimiter         = DialogItems[CFG_DIGCHAR].Data[0];
	Opt.ExtCmdView         = DialogItems[CFG_EXT].Selected;
	Opt.CmdLine            = Max(10,Min(FP_ConWidth()-9,atoi(DialogItems[CFG_EXT_W].Data)));
	Opt.CmdLength          = Max(5,Min(FP_ConHeight()-5,atoi(DialogItems[CFG_EXT_H].Data)));
	Opt.IOBuffSize         = Max((DWORD)FTR_MINBUFFSIZE,Str2Size(DialogItems[CFG_BUFFSIZE].Data));
	strcpy(Opt.DescriptionNames,DialogItems[CFG_DESC].Data);
	strcpy(Opt.DefaultPassword,DialogItems[CFG_PASS].Data);
	strcpy(Opt.Firewall,DialogItems[CFG_FIRE].Data);
	Opt.CmdLogLimit        = atoi(DialogItems[CFG_LOGLIMIT].Data);
	strcpy(Opt.CmdLogFile, DialogItems[CFG_LOGFILE].Data);
	Opt.LogOutput          = DialogItems[CFG_LOGDIR].Selected;
	Opt.PassiveMode        = DialogItems[CFG_PASV].Selected;
//Write to REG
	WriteCfg();

	if(FTPPanels[0]) FTPPanels[0]->Invalidate();

	if(FTPPanels[1]) FTPPanels[1]->Invalidate();

	return TRUE;
}
Example #27
0
/*--------------------------------------------------------------------------*/
static int zbeshg(double *x1r, double *x1i, double *alpha,
                  int *kode, int *k, int *n, double *yr,
                  double *yi, int *nz, double *wr,
                  double *wi, int *ierr)
{
    int iOne = 1;
    int iTwo = 2;
    double dNegOne = -1.;

    double nan = C2F(returnanan)();

    int iVal = 0;
    int nn = 0;
    double xr = *x1r;
    double xi = *x1i;
    int intalpha = (int)(*alpha);

    /* extends cbesi for the case where alpha is negative */

    if (ISNAN(xr) || ISNAN(xi) || ISNAN(*alpha))
    {
        /* NaN case */
        C2F(dset)(n, &nan, &yr[0], &iOne);
        C2F(dset)(n, &nan, &yi[0], &iOne);

        *ierr = 4;
    }
    else if (*alpha >= 0.)
    {
        C2F(zbesh)(&xr, &xi, alpha, kode, k, n, &yr[0], &yi[0], nz, ierr);
        if (*ierr == 1 || *ierr == 2 || *ierr >= 4)
        {
            C2F(dset)(n, &nan, &yr[0], &iOne);
            C2F(dset)(n, &nan, &yi[0], &iOne);
        }
    }
    else if (*alpha == (double)intalpha)
    {
        double a1 = 0.;
        /* alpha < 0 and int, */
        /*  transform to positive value of alpha */
        if (*alpha - 1 + *n >= 0.)
        {
            /* 0 is between alpha and alpha+n */
            a1 = 0.;
            /* Computing MIN */
            nn = Min(*n, (int) (-(*alpha)));
        }
        else
        {
            a1 = -(*alpha - 1 + *n);
            nn = *n;
        }
        C2F(zbesh)(&xr, &xi, &a1, kode, k, n, &wr[0], &wi[0], nz, ierr);
        if (*ierr == 1 || *ierr == 2 || *ierr >= 4)
        {
            C2F(dset)(n, &nan, &yr[0], &iOne);
            C2F(dset)(n, &nan, &yi[0], &iOne);
        }
        else
        {
            if (*n > nn)
            {
                /* 0 is between alpha and alpha+n */
                iVal = *n - nn;
                C2F(dcopy)(&iVal, &wr[0], &iOne, &yr[nn], &iOne);
                C2F(dcopy)(&iVal, &wi[0], &iOne, &yi[nn], &iOne);
                C2F(dcopy)(&nn, &wr[1], &iOne, &yr[0], &iOne);
                C2F(dcopy)(&nn, &wi[1], &iOne, &yi[0], &iOne);
            }
            else
            {
                /* alpha and alpha+n are negative */
                C2F(dcopy)(n, &wr[0], &iOne, &yr[0], &iOne);
                C2F(dcopy)(n, &wi[0], &iOne, &yi[0], &iOne);
            }
        }
        iVal = (nn - (((int) fabs(*alpha) + 1) % 2) + 1) / 2;
        C2F(dscal)(&iVal, &dNegOne, &yr[((int) fabs(*alpha) + 1) % 2], &iTwo);
        C2F(dscal)(&iVal, &dNegOne, &yi[((int) fabs(*alpha) + 1) % 2], &iTwo);
    }
    else
    {
        int nz1 = 0;
        double a1 = 0.;
        /* first alpha is negative non int, transform to positive value of alpha */
        if (*alpha - 1. + *n >= 0.)
        {
            /* 0 is between alpha and alpha+n */
            nn = (int) (-(*alpha)) + 1;
        }
        else
        {
            nn = *n;
        }

        /* compute for negative value of alpha+k, transform problem for */
        /* a1:a1+(nn-1) with a1 positive  a1+k =abs(alpha+nn-k) */
        a1 = -(*alpha - 1. + nn);
        C2F(zbesh)(&xr, &xi, &a1, kode, k, n, &wr[0], &wi[0], &nz1, ierr);
        *nz = Max(nz1, 0);
        if (*ierr == 0)
        {
            double a = cos(a1 * M_PI);
            double b = sin(a1 * M_PI);
            if (*k == 1)
            {
                C2F(wscal)(&nn, &a, &b, &wr[0], &wi[0], &iOne);
            }
            else
            {
                double dNegB = -b;
                C2F(wscal)(&nn, &a, &dNegB, &wr[0], &wi[0], &iOne);
            }
            /* change sign to take into account that sin((a1+k)*pi) and cos((a1+k)*pi) */
            /* changes sign with k */
            if (nn >= 2)
            {
                iVal = nn / 2;
                C2F(dscal)(&iVal, &dNegOne, &wr[1], &iTwo);
                C2F(dscal)(&iVal, &dNegOne, &wi[1], &iTwo);
            }
        }
        else if (*ierr == 1 || *ierr == 2 || *ierr >= 4)
        {
            C2F(dset)(&nn, &nan, &wr[0], &iOne);
            C2F(dset)(&nn, &nan, &wi[0], &iOne);
        }

        /* store the result in the correct order */
        C2F(dcopy)(&nn, &wr[0], &iOne, &yr[0], &iOne);
        C2F(dcopy)(&nn, &wi[0], &iOne, &yi[0], &iOne);

        /* compute for positive value of alpha+k is any */
        if (*n > nn)
        {
            int ier = 0;
            a1 = 1. - a1;
            iVal = *n - nn;
            C2F(zbesh)(&xr, &xi, &a1, kode, k, &iVal, &yr[nn], &yi[nn], nz, &ier);
            if (ier == 1 || ier == 2 || ier >= 4)
            {
                iVal = *n - nn;
                C2F(dset)(&iVal, &nan, &yr[nn], &iOne);
                C2F(dset)(&iVal, &nan, &yi[nn], &iOne);
            }
            *ierr = Max(*ierr, ier);
        }
    }
    return 0;
}
Example #28
0
void Button::SetRepeatDelay(float delay)
{
    repeatDelay_ = Max(delay, 0.0f);
}
Example #29
0
   Copyright (c) 2009-2016, Jack Poulson
   All rights reserved.

   This file is part of Elemental and is under the BSD 2-Clause License, 
   which can be found in the LICENSE file in the root directory, or at 
   http://opensource.org/licenses/BSD-2-Clause
*/
#include "El.hpp"

namespace El {

template<typename Real>
void LowerClip( Matrix<Real>& X, Real lowerBound )
{
    DEBUG_ONLY(CSE cse("LowerClip"))
    auto lowerClip = [&]( Real alpha ) { return Max(lowerBound,alpha); };
    EntrywiseMap( X, function<Real(Real)>(lowerClip) );
}

template<typename Real>
void UpperClip( Matrix<Real>& X, Real upperBound )
{
    DEBUG_ONLY(CSE cse("UpperClip"))
    auto upperClip = [&]( Real alpha ) { return Min(upperBound,alpha); };
    EntrywiseMap( X, function<Real(Real)>(upperClip) );
}

template<typename Real>
void Clip( Matrix<Real>& X, Real lowerBound, Real upperBound )
{
    DEBUG_ONLY(CSE cse("Clip"))
Example #30
0
/**
 * This function is called by the analyze function iff
 * the geometry_analyze() function give it its pointer
 * (this is always the case so far).
 * The geometry_analyze() function is also responsible
 * of deciding the number of "sample" rows we will receive
 * here. It is able to give use other 'custom' data, but we
 * won't use them so far.
 *
 * Our job is to build some statistics on the sample data
 * for use by operator estimators.
 *
 * Currently we only need statistics to estimate the number of rows
 * overlapping a given extent (estimation function bound
 * to the && operator).
 *
 */
static void
compute_geometry_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
                       int samplerows, double totalrows)
{
	MemoryContext old_context;
	int i;
	int geom_stats_size;
	GBOX **sampleboxes;
	GEOM_STATS *geomstats;
	bool isnull;
	int null_cnt=0, notnull_cnt=0, examinedsamples=0;
	GBOX *sample_extent=NULL;
	double total_width=0;
	double total_boxes_area=0;
	int total_boxes_cells=0;
	double cell_area;
	double cell_width;
	double cell_height;
#if USE_STANDARD_DEVIATION
	/* for standard deviation */
	double avgLOWx, avgLOWy, avgHIGx, avgHIGy;
	double sumLOWx=0, sumLOWy=0, sumHIGx=0, sumHIGy=0;
	double sdLOWx=0, sdLOWy=0, sdHIGx=0, sdHIGy=0;
	GBOX *newhistobox=NULL;
#endif
	double geow, geoh; /* width and height of histogram */
	int histocells;
	int cols, rows; /* histogram grid size */
	GBOX histobox;

	/*
	 * This is where geometry_analyze
	 * should put its' custom parameters.
	 */
	/* void *mystats = stats->extra_data; */

	/*
	 * We'll build an histogram having from 40 to 400 boxesPerSide
	 * Total number of cells is determined by attribute stat
	 * target. It can go from  1600 to 160000 (stat target: 10,1000)
	 */
	histocells = 160*stats->attr->attstattarget;


	POSTGIS_DEBUG(2, "compute_geometry_stats called");
	POSTGIS_DEBUGF(3, " samplerows: %d", samplerows);
	POSTGIS_DEBUGF(3, " histogram cells: %d", histocells);

	/*
	 * We might need less space, but don't think
	 * its worth saving...
	 */
	sampleboxes = palloc(sizeof(GBOX *)*samplerows);

	/*
	 * First scan:
	 *  o find extent of the sample rows
	 *  o count null-infinite/not-null values
	 *  o compute total_width
	 *  o compute total features's box area (for avgFeatureArea)
	 *  o sum features box coordinates (for standard deviation)
	 */
	for (i=0; i<samplerows; i++)
	{
		Datum datum;
		GSERIALIZED *geom;
		GBOX box;

		datum = fetchfunc(stats, i, &isnull);

		/*
		 * Skip nulls
		 */
		if ( isnull )
		{
			null_cnt++;
			continue;
		}

		geom = (GSERIALIZED *)PG_DETOAST_DATUM(datum);

		if ( LW_FAILURE == gserialized_datum_get_gbox_p(datum, &box) )
		{
			/* Skip empty geometry */
			POSTGIS_DEBUGF(3, " skipped empty geometry %d", i);

			continue;
		}

		/*
		 * Skip infinite geoms
		 */
		if ( ! finite(box.xmin) ||
		        ! finite(box.xmax) ||
		        ! finite(box.ymin) ||
		        ! finite(box.ymax) )
		{
			POSTGIS_DEBUGF(3, " skipped infinite geometry %d", i);

			continue;
		}

		/*
		 * Cache bounding box
		 * TODO: reduce BOX2DFLOAT4 copies
		 */
		sampleboxes[notnull_cnt] = palloc(sizeof(GBOX));
		memcpy(sampleboxes[notnull_cnt], &box, sizeof(GBOX));

		/*
		 * Add to sample extent union
		 */
		if ( ! sample_extent )
		{
			sample_extent = palloc(sizeof(GBOX));
			memcpy(sample_extent, &box, sizeof(GBOX));
		}
		else
		{
			sample_extent->xmax = Max(sample_extent->xmax,
			                                  box.xmax);
			sample_extent->ymax = Max(sample_extent->ymax,
			                                  box.ymax);
			sample_extent->xmin = Min(sample_extent->xmin,
			                                  box.xmin);
			sample_extent->ymin = Min(sample_extent->ymin,
			                                  box.ymin);
		}

		/** TODO: ask if we need geom or bvol size for stawidth */
		total_width += geom->size;
		total_boxes_area += (box.xmax-box.xmin)*(box.ymax-box.ymin);

#if USE_STANDARD_DEVIATION
		/*
		 * Add bvol coordinates to sum for standard deviation
		 * computation.
		 */
		sumLOWx += box.xmin;
		sumLOWy += box.ymin;
		sumHIGx += box.xmax;
		sumHIGy += box.ymax;
#endif

		notnull_cnt++;

		/* give backend a chance of interrupting us */
		vacuum_delay_point();

	}

	if ( ! notnull_cnt )
	{
		elog(NOTICE, " no notnull values, invalid stats");
		stats->stats_valid = false;
		return;
	}

#if USE_STANDARD_DEVIATION

	POSTGIS_DEBUGF(3, " sample_extent: xmin,ymin: %f,%f",
	               sample_extent->xmin, sample_extent->ymin);
	POSTGIS_DEBUGF(3, " sample_extent: xmax,ymax: %f,%f",
	               sample_extent->xmax, sample_extent->ymax);

	/*
	 * Second scan:
	 *  o compute standard deviation
	 */
	avgLOWx = sumLOWx/notnull_cnt;
	avgLOWy = sumLOWy/notnull_cnt;
	avgHIGx = sumHIGx/notnull_cnt;
	avgHIGy = sumHIGy/notnull_cnt;
	for (i=0; i<notnull_cnt; i++)
	{
		GBOX *box;
		box = (GBOX *)sampleboxes[i];

		sdLOWx += (box->xmin - avgLOWx) * (box->xmin - avgLOWx);
		sdLOWy += (box->ymin - avgLOWy) * (box->ymin - avgLOWy);
		sdHIGx += (box->xmax - avgHIGx) * (box->xmax - avgHIGx);
		sdHIGy += (box->ymax - avgHIGy) * (box->ymax - avgHIGy);
	}
	sdLOWx = sqrt(sdLOWx/notnull_cnt);
	sdLOWy = sqrt(sdLOWy/notnull_cnt);
	sdHIGx = sqrt(sdHIGx/notnull_cnt);
	sdHIGy = sqrt(sdHIGy/notnull_cnt);

	POSTGIS_DEBUG(3, " standard deviations:");
	POSTGIS_DEBUGF(3, "  LOWx - avg:%f sd:%f", avgLOWx, sdLOWx);
	POSTGIS_DEBUGF(3, "  LOWy - avg:%f sd:%f", avgLOWy, sdLOWy);
	POSTGIS_DEBUGF(3, "  HIGx - avg:%f sd:%f", avgHIGx, sdHIGx);
	POSTGIS_DEBUGF(3, "  HIGy - avg:%f sd:%f", avgHIGy, sdHIGy);

	histobox.xmin = Max((avgLOWx - SDFACTOR * sdLOWx),
	                       sample_extent->xmin);
	histobox.ymin = Max((avgLOWy - SDFACTOR * sdLOWy),
	                       sample_extent->ymin);
	histobox.xmax = Min((avgHIGx + SDFACTOR * sdHIGx),
	                       sample_extent->xmax);
	histobox.ymax = Min((avgHIGy + SDFACTOR * sdHIGy),
	                       sample_extent->ymax);

	POSTGIS_DEBUGF(3, " sd_extent: xmin,ymin: %f,%f",
	               histobox.xmin, histobox.ymin);
	POSTGIS_DEBUGF(3, " sd_extent: xmax,ymax: %f,%f",
	               histobox.xmin, histobox.ymax);

	/*
	 * Third scan:
	 *   o skip hard deviants
	 *   o compute new histogram box
	 */
	for (i=0; i<notnull_cnt; i++)
	{
		GBOX *box;
		box = (GBOX *)sampleboxes[i];

		if ( box->xmin > histobox.xmax ||
		        box->xmax < histobox.xmin ||
		        box->ymin > histobox.ymax ||
		        box->ymax < histobox.ymin )
		{
			POSTGIS_DEBUGF(4, " feat %d is an hard deviant, skipped", i);

			sampleboxes[i] = NULL;
			continue;
		}
		if ( ! newhistobox )
		{
			newhistobox = palloc(sizeof(GBOX));
			memcpy(newhistobox, box, sizeof(GBOX));
		}
		else
		{
			if ( box->xmin < newhistobox->xmin )
				newhistobox->xmin = box->xmin;
			if ( box->ymin < newhistobox->ymin )
				newhistobox->ymin = box->ymin;
			if ( box->xmax > newhistobox->xmax )
				newhistobox->xmax = box->xmax;
			if ( box->ymax > newhistobox->ymax )
				newhistobox->ymax = box->ymax;
		}
	}

	/*
	 * Set histogram extent as the intersection between
	 * standard deviation based histogram extent
	 * and computed sample extent after removal of
	 * hard deviants (there might be no hard deviants).
	 */
	if ( histobox.xmin < newhistobox->xmin )
		histobox.xmin = newhistobox->xmin;
	if ( histobox.ymin < newhistobox->ymin )
		histobox.ymin = newhistobox->ymin;
	if ( histobox.xmax > newhistobox->xmax )
		histobox.xmax = newhistobox->xmax;
	if ( histobox.ymax > newhistobox->ymax )
		histobox.ymax = newhistobox->ymax;


#else /* ! USE_STANDARD_DEVIATION */

	/*
	* Set histogram extent box
	*/
	histobox.xmin = sample_extent->xmin;
	histobox.ymin = sample_extent->ymin;
	histobox.xmax = sample_extent->xmax;
	histobox.ymax = sample_extent->ymax;
#endif /* USE_STANDARD_DEVIATION */


	POSTGIS_DEBUGF(3, " histogram_extent: xmin,ymin: %f,%f",
	               histobox.xmin, histobox.ymin);
	POSTGIS_DEBUGF(3, " histogram_extent: xmax,ymax: %f,%f",
	               histobox.xmax, histobox.ymax);


	geow = histobox.xmax - histobox.xmin;
	geoh = histobox.ymax - histobox.ymin;

	/*
	 * Compute histogram cols and rows based on aspect ratio
	 * of histogram extent
	 */
	if ( ! geow && ! geoh )
	{
		cols = 1;
		rows = 1;
		histocells = 1;
	}
	else if ( ! geow )
	{
		cols = 1;
		rows = histocells;
	}
	else if ( ! geoh )
	{
		cols = histocells;
		rows = 1;
	}
	else
	{
		if ( geow<geoh)
		{
			cols = ceil(sqrt((double)histocells*(geow/geoh)));
			rows = ceil((double)histocells/cols);
		}
		else
		{
			rows = ceil(sqrt((double)histocells*(geoh/geow)));
			cols = ceil((double)histocells/rows);
		}
		histocells = cols*rows;
	}

	POSTGIS_DEBUGF(3, " computed histogram grid size (CxR): %dx%d (%d cells)", cols, rows, histocells);


	/*
	 * Create the histogram (GEOM_STATS)
	 */
	old_context = MemoryContextSwitchTo(stats->anl_context);
	geom_stats_size=sizeof(GEOM_STATS)+(histocells-1)*sizeof(float4);
	geomstats = palloc(geom_stats_size);
	MemoryContextSwitchTo(old_context);

	geomstats->avgFeatureArea = total_boxes_area/notnull_cnt;
	geomstats->xmin = histobox.xmin;
	geomstats->ymin = histobox.ymin;
	geomstats->xmax = histobox.xmax;
	geomstats->ymax = histobox.ymax;
	geomstats->cols = cols;
	geomstats->rows = rows;

	/* Initialize all values to 0 */
	for (i=0; i<histocells; i++) geomstats->value[i] = 0;

	cell_width = geow/cols;
	cell_height = geoh/rows;
	cell_area = cell_width*cell_height;

	POSTGIS_DEBUGF(4, "cell_width: %f", cell_width);
	POSTGIS_DEBUGF(4, "cell_height: %f", cell_height);


	/*
	 * Fourth scan:
	 *  o fill histogram values with the number of
	 *    features' bbox overlaps: a feature's bvol
	 *    can fully overlap (1) or partially overlap
	 *    (fraction of 1) an histogram cell.
	 *
	 *  o compute total cells occupation
	 *
	 */
	for (i=0; i<notnull_cnt; i++)
	{
		GBOX *box;
		int x_idx_min, x_idx_max, x;
		int y_idx_min, y_idx_max, y;
		int numcells=0;

		box = (GBOX *)sampleboxes[i];
		if ( ! box ) continue; /* hard deviant.. */

		/* give backend a chance of interrupting us */
		vacuum_delay_point();

		POSTGIS_DEBUGF(4, " feat %d box is %f %f, %f %f",
		               i, box->xmax, box->ymax,
		               box->xmin, box->ymin);

		/* Find first overlapping column */
		x_idx_min = (box->xmin-geomstats->xmin) / geow * cols;
		if (x_idx_min <0) x_idx_min = 0;
		if (x_idx_min >= cols) x_idx_min = cols-1;

		/* Find first overlapping row */
		y_idx_min = (box->ymin-geomstats->ymin) / geoh * rows;
		if (y_idx_min <0) y_idx_min = 0;
		if (y_idx_min >= rows) y_idx_min = rows-1;

		/* Find last overlapping column */
		x_idx_max = (box->xmax-geomstats->xmin) / geow * cols;
		if (x_idx_max <0) x_idx_max = 0;
		if (x_idx_max >= cols ) x_idx_max = cols-1;

		/* Find last overlapping row */
		y_idx_max = (box->ymax-geomstats->ymin) / geoh * rows;
		if (y_idx_max <0) y_idx_max = 0;
		if (y_idx_max >= rows) y_idx_max = rows-1;

		POSTGIS_DEBUGF(4, " feat %d overlaps columns %d-%d, rows %d-%d",
		               i, x_idx_min, x_idx_max, y_idx_min, y_idx_max);

		/*
		 * the {x,y}_idx_{min,max}
		 * define the grid squares that the box intersects
		 */
		for (y=y_idx_min; y<=y_idx_max; y++)
		{
			for (x=x_idx_min; x<=x_idx_max; x++)
			{
				geomstats->value[x+y*cols] += 1;
				numcells++;
			}
		}

		/*
		 * before adding to the total cells
		 * we could decide if we really
		 * want this feature to count
		 */
		total_boxes_cells += numcells;

		examinedsamples++;
	}

	POSTGIS_DEBUGF(3, " examined_samples: %d/%d", examinedsamples, samplerows);

	if ( ! examinedsamples )
	{
		elog(NOTICE, " no examined values, invalid stats");
		stats->stats_valid = false;

		POSTGIS_DEBUG(3, " no stats have been gathered");

		return;
	}

	/** TODO: what about null features (TODO) */
	geomstats->avgFeatureCells = (float4)total_boxes_cells/examinedsamples;

	POSTGIS_DEBUGF(3, " histo: total_boxes_cells: %d", total_boxes_cells);
	POSTGIS_DEBUGF(3, " histo: avgFeatureArea: %f", geomstats->avgFeatureArea);
	POSTGIS_DEBUGF(3, " histo: avgFeatureCells: %f", geomstats->avgFeatureCells);


	/*
	 * Normalize histogram
	 *
	 * We divide each histogram cell value
	 * by the number of samples examined.
	 *
	 */
	for (i=0; i<histocells; i++)
		geomstats->value[i] /= examinedsamples;

	{
		int x, y;
		for (x=0; x<cols; x++)
		{
			for (y=0; y<rows; y++)
			{
				POSTGIS_DEBUGF(4, " histo[%d,%d] = %.15f", x, y, geomstats->value[x+y*cols]);
			}
		}
	}


	/*
	 * Write the statistics data
	 */
	stats->stakind[0] = STATISTIC_KIND_GEOMETRY;
	stats->staop[0] = InvalidOid;
	stats->stanumbers[0] = (float4 *)geomstats;
	stats->numnumbers[0] = geom_stats_size/sizeof(float4);

	stats->stanullfrac = (float4)null_cnt/samplerows;
	stats->stawidth = total_width/notnull_cnt;
	stats->stadistinct = -1.0;

	POSTGIS_DEBUGF(3, " out: slot 0: kind %d (STATISTIC_KIND_GEOMETRY)",
	               stats->stakind[0]);
	POSTGIS_DEBUGF(3, " out: slot 0: op %d (InvalidOid)", stats->staop[0]);
	POSTGIS_DEBUGF(3, " out: slot 0: numnumbers %d", stats->numnumbers[0]);
	POSTGIS_DEBUGF(3, " out: null fraction: %d/%d=%g", null_cnt, samplerows, stats->stanullfrac);
	POSTGIS_DEBUGF(3, " out: average width: %d bytes", stats->stawidth);
	POSTGIS_DEBUG(3, " out: distinct values: all (no check done)");

	stats->stats_valid = true;
}