GLuint MeshTexturizer::Imp::textureAlloc(const TRaster32P &ras, const TRaster32P &aux,
										 int x, int y, int textureLx, int textureLy,
										 bool premultiplied)
{
	struct locals {
		static void clearMatte(const TRaster32P &ras, int xBegin, int yBegin, int xEnd, int yEnd)
		{
			for (int y = yBegin; y != yEnd; ++y) {
				TPixel32 *line = ras->pixels(y), *pixEnd = line + xEnd;

				for (TPixel32 *pix = line + xBegin; pix != pixEnd; ++pix)
					pix->m = 0;
			}
		}

		static void clearMatte_border(const TRaster32P &ras, int border0, int border1)
		{
			assert(border0 < border1);

			// Horizontal
			clearMatte(ras, border0, border0, ras->getLx() - border0, border1);
			clearMatte(ras, border0, ras->getLy() - border1, ras->getLx() - border0, ras->getLy() - border0);

			// Vertical
			clearMatte(ras, border0, border1, border1, ras->getLy() - border1);
			clearMatte(ras, ras->getLx() - border1, border1, ras->getLx() - border0, ras->getLy() - border1);
		}
	}; // locals

	// Prepare the texture tile
	assert(aux->getLx() >= textureLx + TOTAL_BORDER_2 && aux->getLy() >= textureLy + TOTAL_BORDER_2);

	TRect rasRect(x, y, x + textureLx - 1, y + textureLy - 1);
	rasRect = rasRect.enlarge(premultiplied ? COPIED_BORDER : COPIED_BORDER + NONPREM_BORDER);
	rasRect = rasRect * ras->getBounds();

	TRect auxRect(rasRect - TPoint(x - TOTAL_BORDER, y - TOTAL_BORDER));

	// An auxiliary raster must be used to supply the transparent border
	TRaster32P tex(aux->extract(0, 0, textureLx + TOTAL_BORDER_2 - 1, textureLy + TOTAL_BORDER_2 - 1));
	tex->clear();
	aux->extract(auxRect)->copy(ras->extract(rasRect));

	if (!premultiplied && NONPREM_BORDER > 0)
		locals::clearMatte_border(aux, TRANSP_BORDER - NONPREM_BORDER, TRANSP_BORDER);

	// Pass the raster into VRAM
	GLuint texId;
	glGenTextures(1, &texId);
	glBindTexture(GL_TEXTURE_2D, texId);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);	  // These must be used on a bound texture,
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);	  // and are remembered in the OpenGL context.
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // They can be set here, no need for
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // the user to do it.

	glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->getWrap());
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	glTexImage2D(GL_TEXTURE_2D,
				 0,				   // one level only
				 GL_RGBA,		   // pixel channels count
				 tex->getLx(),	 // width
				 tex->getLy(),	 // height
				 0,				   // border size
				 TGL_FMT,		   // pixel format
				 GL_UNSIGNED_BYTE, // pixel data type
				 (GLvoid *)tex->getRawData());

	return texId;
}
Exemple #2
0
// -------------------------------------------------------------------------
void ctkQImageView::update( bool zoomChanged,
  bool sizeChanged )
{
  Q_D( ctkQImageView );
  if( d->SliceNumber >= 0 && d->SliceNumber < d->ImageList.size() )
    {
    const QImage * img = & ( d->ImageList[ d->SliceNumber ] );
    if( zoomChanged || sizeChanged )
      {
      if( this->width() > 0 &&  this->height() > 0 
        && d->TmpXMax > d->TmpXMin && d->TmpYMax > d->TmpYMin)
        {
        int tmpXRange = d->TmpXMax - d->TmpXMin;
        int tmpYRange = d->TmpYMax - d->TmpYMin;
        double tmpAspectRatio = static_cast<double>(tmpYRange) / tmpXRange;
        double screenAspectRatio = static_cast<double>(this->height())
          / this->width();
        if( screenAspectRatio > tmpAspectRatio )
          {
          int extraTmpYAbove = d->TmpYMin;
          int extraTmpYBelow = img->height() - d->TmpYMax;
          int extraTmpYNeeded = tmpXRange * screenAspectRatio 
            - tmpYRange;
          int minExtra = extraTmpYAbove;
          if( extraTmpYBelow < minExtra )
            {
            minExtra = extraTmpYBelow;
            }
          if(2 * minExtra >= extraTmpYNeeded)
            {
            int minNeeded = extraTmpYNeeded / 2.0;
            int maxNeeded = extraTmpYNeeded - minNeeded;
            d->TmpYMin -= minNeeded;
            d->TmpYMax += maxNeeded;
            }
          else if(extraTmpYAbove + extraTmpYBelow >= extraTmpYNeeded)
            {
            if(extraTmpYAbove < extraTmpYBelow)
              {
              d->TmpYMin = 0;
              d->TmpYMax += extraTmpYNeeded - extraTmpYAbove;
              }
            else
              {
              d->TmpYMax = img->height();
              d->TmpYMin -= extraTmpYNeeded - extraTmpYBelow;
              }
            }
          else
            {
            d->TmpYMin = 0;
            d->TmpYMax = img->height();
            }
          d->TmpImage = QPixmap( this->width(),
            static_cast<unsigned int>( 
              static_cast<double>(d->TmpYMax - d->TmpYMin) 
              / (d->TmpXMax - d->TmpXMin)
              * this->width() + 0.5 ) );
          }
        else if(screenAspectRatio < tmpAspectRatio)
          {
          int extraTmpXLeft = d->TmpXMin;
          int extraTmpXRight = img->width() - d->TmpXMax;
          int extraTmpXNeeded = static_cast<double>(tmpYRange) 
            / screenAspectRatio - tmpXRange;
          int minExtra = extraTmpXLeft;
          if( extraTmpXRight < minExtra )
            {
            minExtra = extraTmpXRight;
            }
          if(2 * minExtra >= extraTmpXNeeded)
            {
            int minNeeded = extraTmpXNeeded / 2.0;
            int maxNeeded = extraTmpXNeeded - minNeeded;
            d->TmpXMin -= minNeeded;
            d->TmpXMax += maxNeeded;
            }
          else if(extraTmpXLeft + extraTmpXRight >= extraTmpXNeeded)
            {
            if(extraTmpXLeft < extraTmpXRight)
              {
              d->TmpXMin = 0;
              d->TmpXMax += extraTmpXNeeded - extraTmpXLeft;
              }
            else
              {
              d->TmpXMax = img->width();
              d->TmpXMin -= extraTmpXNeeded - extraTmpXRight;
              }
            }
           else
            {
            d->TmpXMin = 0;
            d->TmpXMax = img->width();
            }
          d->TmpImage = QPixmap( static_cast<unsigned int>( this->height()
            / ( static_cast<double>(d->TmpYMax - d->TmpYMin) 
            / (d->TmpXMax - d->TmpXMin) ) 
            + 0.5 ), this->height() );
          }
        else
          {
          d->TmpImage = QPixmap( this->width(),  this->height() );
          }
        }
      }

    if( d->TmpImage.width() > 0 &&  d->TmpImage.height() > 0)
      {
      QRectF target( 0, 0, d->TmpImage.width(), d->TmpImage.height() );
      double sourceX = d->TmpXMin;
      double sourceY = d->TmpYMin;
      double sourceW = d->TmpXMax - d->TmpXMin;
      double sourceH = d->TmpYMax - d->TmpYMin;
      QPainter painter( &(d->TmpImage) );
      QImage tmpI = *img;
      if( d->InvertImage )
        {
        tmpI.invertPixels();
        }
      if( d->FlipXAxis || d->FlipYAxis )
        {
        tmpI = tmpI.mirrored( d->FlipXAxis, d->FlipYAxis );
        if( d->FlipXAxis )
          {
          sourceX = tmpI.width() - (d->TmpXMax - d->TmpXMin) - d->TmpXMin;
          }
        if( d->FlipYAxis )
          {
          sourceY = tmpI.height() - (d->TmpYMax - d->TmpYMin) - d->TmpYMin;
          }
        }
      QRectF source( sourceX, sourceY, sourceW, sourceH );
      painter.drawPixmap( target, QPixmap::fromImage( tmpI ), source );

      //if( ! sizeChanged )
        {
        int maxNumCharsPerLine = 50;
        int fontPointSize = 12;
        if( fontPointSize * maxNumCharsPerLine > this->width() )
          {
          fontPointSize = this->width() / maxNumCharsPerLine;
          }
        if( fontPointSize > 7 )
          {
          QString fontFamily( "Helvetica" );
          QFont textFont( fontFamily, fontPointSize );
          painter.setFont( textFont );
          QColor textColor;
          textColor.setNamedColor( "lime" );
          textColor.setAlpha( 128 );
          painter.setPen( textColor );
    
          int textFlags = Qt::AlignLeft | Qt::TextDontClip;
    
          QRectF pointRect( 0, 0, 1, 1 );
          QRectF spaceBound = painter.boundingRect( pointRect, textFlags,
            "X" );
    
          if( img->isGrayscale() )
            {
            QString intString = "Intensity Range = ";
            intString.append( QString::number( d->IntensityMin,
              'f', 3 ) );
            intString.append( " - " );
            intString.append( QString::number( d->IntensityMax,
              'f', 3 ) );
            QRectF intBound = painter.boundingRect( pointRect, textFlags,
              intString );
            QRectF intRect( 
              spaceBound.width()/2,
              spaceBound.height()/8,
              intBound.width(), intBound.height() );
            painter.drawText( intRect, textFlags, intString,
              &intBound );

            QString wlString = "W / L = ";
            wlString.append( QString::number( this->intensityWindow(),
              'f', 3 ) );
            wlString.append( " / " );
            wlString.append( QString::number( this->intensityLevel(),
              'f', 3 ) );
            QRectF wlBound = painter.boundingRect( pointRect, textFlags,
              wlString );
            QRectF wlRect( 
              spaceBound.width()/2,
              intRect.y() + intRect.height() + spaceBound.height()/8,
              wlBound.width(), wlBound.height() );
            painter.drawText( wlRect, textFlags, wlString,
              &wlBound );
            }

          QString spacingString = "Spacing = ";
          spacingString.append( QString::number( this->xSpacing(),
            'f', 3 ) );
          spacingString.append( ", " );
          spacingString.append( QString::number( this->ySpacing(),
            'f', 3 ) );
          spacingString.append( ", " );
          spacingString.append( QString::number( this->sliceThickness(),
            'f', 3 ) );
          QRectF spacingBound = painter.boundingRect( pointRect, textFlags,
            spacingString );
          QRectF spacingRect( 
            this->width() - spacingBound.width() - spaceBound.width()/2,
            this->height() - spacingBound.height() - spaceBound.height()/8,
            spacingBound.width(), spacingBound.height() );
          painter.drawText( spacingRect, textFlags, spacingString,
            &spacingBound );
    
          QString dimString = "Size = ";
          dimString.append( 
            QString::number( d->ImageList[ d->SliceNumber ].width() ) );
          dimString.append( ", " );
          dimString.append( 
            QString::number( d->ImageList[ d->SliceNumber ].height() ) );
          dimString.append( ", " );
          dimString.append( 
            QString::number( d->ImageList.size() ) );
          QRectF dimBound = painter.boundingRect( pointRect, textFlags,
            dimString );
          QRectF dimRect( 
            this->width() - dimBound.width() - spaceBound.width()/2,
            spacingBound.y() - dimBound.height() - spaceBound.height()/8,
            dimBound.width(), dimBound.height() );
          painter.drawText( dimRect, textFlags, dimString, &dimBound );
    
          QString rasString = "RAS = ";
          rasString.append( QString::number( 
            this->xPosition() * this->xSpacing(), 'f', 3 ) );
          rasString.append( ", " );
          rasString.append( QString::number( 
            this->yPosition() * this->ySpacing(), 'f', 3 ) );
          rasString.append( ", " );
          rasString.append( QString::number( 
            this->slicePosition() * this->sliceSpacing(), 'f', 3 ) );
          QRectF rasBound = painter.boundingRect( pointRect, textFlags,
            rasString );
          QRectF rasRect( 
            spaceBound.width()/2,
            this->height() - rasBound.height() - spaceBound.height()/8,
            rasBound.width(), rasBound.height() );
          painter.drawText( rasRect, textFlags, rasString,
            &rasBound );
    
          QString ijkString = "IJK = ";
          ijkString.append( QString::number( this->xPosition() ) );
          ijkString.append( ", " );
          ijkString.append( QString::number( this->yPosition() ) );
          ijkString.append( ", " );
          ijkString.append( QString::number( this->slicePosition() ) );
          QRectF ijkBound = painter.boundingRect( pointRect, textFlags,
            ijkString );
          QRectF ijkRect( 
            spaceBound.width()/2,
            rasBound.y() - ijkBound.height() - spaceBound.height()/8,
            ijkBound.width(), ijkBound.height() );
          painter.drawText( ijkRect, textFlags, ijkString, &ijkBound );
    
          QString valString = "Value = ";
          valString.append( QString::number( this->positionValue(),
            'f', 3 ) );
          QRectF valBound = painter.boundingRect( pointRect, textFlags,
            valString );
          QRectF valRect( 
            spaceBound.width()/2,
            ijkBound.y() - valBound.height() - spaceBound.height()/8,
            valBound.width(), valBound.height() );
          painter.drawText( valRect, textFlags, valString, &valBound );
          }
    
        QColor lineColor;
        lineColor.setNamedColor( "red" );
        lineColor.setAlpha( 128 );
        painter.setPen( lineColor );
        double x = ( this->xPosition() - d->TmpXMin ) 
          / (d->TmpXMax - d->TmpXMin) * this->width();
        double y = ( this->yPosition() - d->TmpYMin ) 
          / (d->TmpYMax - d->TmpYMin) * this->height();
        if( d->FlipXAxis )
          {
          x = this->width() - x;
          }
        if( d->FlipYAxis )
          {
          y = this->height() - y;
          }
        QLine lineX( x, 0, x, this->height() );
        painter.drawLine( lineX );
        QLine lineY( 0, y, this->width(), y );
        painter.drawLine( lineY );
        }
      }

    d->Window->setPixmap( d->TmpImage );
    }
  else
    {
    d->Window->setText( "No Image Loaded." );
    }
}