Esempio n. 1
0
void
VolumeBase::createLowresVolume(bool redo)
{
  if (Global::volumeType() == Global::DummyVolume)
    {      
      m_subSamplingLevel = 1;
      m_lowresVolumeSize = m_fullVolumeSize/m_subSamplingLevel;
      return;
    }


  int px2, py2, pz2;
  px2 = StaticFunctions::getPowerOf2(m_fullVolumeSize.x);
  py2 = StaticFunctions::getPowerOf2(m_fullVolumeSize.y);
  pz2 = StaticFunctions::getPowerOf2(m_fullVolumeSize.z);

  int lod = 1;

  int gtsz = StaticFunctions::getPowerOf2(Global::textureSizeLimit());
  gtsz --; // be on the lower side
  if (px2 > gtsz || py2 > gtsz || pz2 > gtsz)
    {
      int maxp2, df;
      maxp2 = qMax(px2, qMax(py2, pz2));
      df = maxp2 - gtsz;  // 2^gtsz = Global::textureSizeLimit()
      lod += df;
    }
  
  gtsz = qMin(26, Global::textureSize()-1);
  if ((px2+py2+pz2) - 3*(lod-1) > gtsz)
    {
      int df0, df;
      df0 = (px2+py2+pz2) - 3*(lod-1) - gtsz; 
      df = df0/3 + (df0%3 > 0);
      lod += df; 
    }
  m_subSamplingLevel = (int)pow((float)2, (float)lod-1);

  // max hardware texture size is 512x512x512
  if ((px2 > 9 || py2 > 9 || pz2 > 9) &&
      m_subSamplingLevel == 1)
    m_subSamplingLevel = 2;


  m_lowresVolumeSize = m_fullVolumeSize/m_subSamplingLevel;
  int height= m_lowresVolumeSize.x;
  int width = m_lowresVolumeSize.y;
  int depth = m_lowresVolumeSize.z;

  int bpv = 1;
  if (m_pvlVoxelType > 0) bpv = 2;

  if (m_lowresVolume) delete [] m_lowresVolume;
  m_lowresVolume = new unsigned char[bpv*height*width*depth];
  memset(m_lowresVolume, 0, bpv*height*width*depth);

  int iend,jend,kend;      
  iend = height;
  jend = width;
  kend = depth;

  unsigned char *tmp;
  tmp = new unsigned char [bpv*jend*iend];
  memset(tmp, 0, bpv*jend*iend);
  
  //-----------
  uchar *g0, *g1, *g2;
  g0 = new unsigned char [bpv*m_width*m_height];
  g1 = new unsigned char [bpv*m_width*m_height];
  g2 = new unsigned char [bpv*m_width*m_height];
  
  if (m_1dHistogram) delete [] m_1dHistogram;
  if (m_2dHistogram) delete [] m_2dHistogram;
  
  m_1dHistogram = new int[256];
  memset(m_1dHistogram, 0, 256*4);
  
  m_2dHistogram = new int[256*256];
  memset(m_2dHistogram, 0, 256*256*4);
  
  float *flhist1D = new float[256];
  memset(flhist1D, 0, 256*4);
  float *flhist2D = new float[256*256];
  memset(flhist2D, 0, 256*256*4);
  //-----------
  
  VolumeFileManager pvlFileManager;
  int slabSize = XmlHeaderFunctions::getSlabsizeFromHeader(m_volumeFile);
  int headerSize = XmlHeaderFunctions::getPvlHeadersizeFromHeader(m_volumeFile);
  QStringList pvlnames = XmlHeaderFunctions::getPvlNamesFromHeader(m_volumeFile);
  if (pvlnames.count() > 0)
    pvlFileManager.setFilenameList(pvlnames);
  pvlFileManager.setBaseFilename(m_volumeFile);
  pvlFileManager.setVoxelType(m_pvlVoxelType);
  pvlFileManager.setDepth(m_depth);
  pvlFileManager.setWidth(m_width);
  pvlFileManager.setHeight(m_height);
  pvlFileManager.setHeaderSize(headerSize); // default is 13 bytes
  pvlFileManager.setSlabSize(slabSize);
  if (!pvlFileManager.exists())
    QMessageBox::information(0, "", "Some problem with pvl.nc files");


  MainWindowUI::mainWindowUI()->menubar->parentWidget()->\
    setWindowTitle(QString("Generating Lowres Version"));
  Global::progressBar()->show();

  int nbytes = bpv*m_width*m_height;
  for(int kslc=0; kslc<kend; kslc++)
    {
      int k = kslc*m_subSamplingLevel;

      Global::progressBar()->setValue((int)(100.0*(float)k/(float)m_depth));
      if (k%10==0) qApp->processEvents();

      uchar *vslice = pvlFileManager.getSlice(k);
      memcpy(g2, vslice, nbytes);

      if (bpv == 1) // uchar
	{
	  for(int j=0; j<m_width*m_height; j++)
	    flhist1D[g2[j]]++;
      
	  if (kslc >= 2)
	    {
	      for(int j=1; j<m_width-1; j++)
		for(int i=1; i<m_height-1; i++)
		  {
		    int gx = (g1[j*m_height+(i+1)] - g1[j*m_height+(i-1)]);
		    int gy = (g1[(j+1)*m_height+i] - g1[(j-1)*m_height+i]);
		    int gz = (g2[j*m_height+i] - g0[j*m_height+i]);
		    int gsum = sqrtf(gx*gx+gy*gy+gz*gz);
		    gsum = qBound(0, gsum, 255);
		    int v = g1[j*m_height+i];
		    flhist2D[gsum*256 + v]++;
		  }
	    }
	}
      else // ushort
	{
	  for(int j=0; j<m_width*m_height; j++)
	    flhist1D[((ushort*)g2)[j]/256]++;
      
	  for(int j=0; j<m_width*m_height; j++)
	    flhist2D[((ushort*)g2)[j]]++;

//	  if (kslc >= 2)
//	    {
//	      for(int j=1; j<m_width-1; j++)
//		for(int i=1; i<m_height-1; i++)
//		  {
//		    int v = ((ushort*)g1)[j*m_height+i];
//		    //flhist2D[v]++;
//		    int gsum = v/256;
//		    int vg = v-gsum*256;
//		    flhist2D[gsum*256 + vg]++;
//		  }
//	    }
	}
      
      uchar *gt = g0;
      g0 = g1;
      g1 = g2;
      g2 = gt;

	
      if (m_subSamplingLevel > 1)
	{
	  int ji=0;
	  if (bpv == 1)
	    {
	      for(int j=0; j<jend; j++)
		{ 
		  int y = j*m_subSamplingLevel;
		  for(int i=0; i<iend; i++) 
		    { 
		      int x = i*m_subSamplingLevel; 
		      tmp[ji] = g2[y*m_height+x];
		      ji++;
		    } 
		}
	    }
	  else
	    {
	      for(int j=0; j<jend; j++)
		{ 
		  int y = j*m_subSamplingLevel;
		  for(int i=0; i<iend; i++) 
		    { 
		      int x = i*m_subSamplingLevel; 
		      ((ushort*)tmp)[ji] = ((ushort*)g2)[y*m_height+x];
		      ji++;
		    } 
		}
	    }
	  memcpy(m_lowresVolume + bpv*kslc*jend*iend,
		 tmp,
		 bpv*jend*iend);
	}	  
      else
	memcpy(m_lowresVolume + bpv*kslc*jend*iend,
	       g2,
	       bpv*jend*iend);
    }

  int actualdepth = StaticFunctions::getScaledown(m_subSamplingLevel, m_depth);
  if (actualdepth < depth)
    {
      // replicate the data
      for (int dd=actualdepth; dd<depth; dd++)
	memcpy(m_lowresVolume + bpv*dd*jend*iend,
	       m_lowresVolume + bpv*(dd-1)*jend*iend,
	       bpv*jend*iend);
    }

  delete [] g0;
  delete [] g1;
  delete [] g2;
  delete [] tmp;
  
  if (m_pvlVoxelType == 0)
    StaticFunctions::generateHistograms(flhist1D, flhist2D,
					m_1dHistogram, m_2dHistogram);
  else // just copy
    {
      for(int i=0; i<256; i++)
	m_1dHistogram[i] = flhist1D[i];
      for(int i=0; i<256*256; i++)
	m_2dHistogram[i] = flhist2D[i];
    }

  delete [] flhist1D;
  delete [] flhist2D;
  
  Global::progressBar()->setValue(100);
  Global::hideProgressBar();
  qApp->processEvents();
}
Esempio n. 2
0
void
ImageStackPlugin::saveTrimmedRGB(QString trimFile,
				 int dmin, int dmax,
				 int wmin, int wmax,
				 int hmin, int hmax)
{
  QStringList dtypes;
  dtypes << "No"
	 << "Yes";

  QString option = QInputDialog::getItem(0,
					 "Save Alpha Channel",
					 "Alpha Channel",
					 dtypes,
					 0,
					 false);
  
  bool saveAlpha = false;
  if (option == "Yes")
    saveAlpha = true;


  QProgressDialog progress("Saving trimmed RGB volume",
			   "Cancel",
			   0, 100,
			   0);
  progress.setMinimumDuration(0);

  int nX, nY, nZ;
  nX = m_depth;
  nY = m_width;
  nZ = m_height;

  int d, w, h;
  d = dmax-dmin+1;
  w = wmax-wmin+1;
  h = hmax-hmin+1;

  int nbytes = nY*nZ;
  uchar *tmpR = new uchar[nbytes];
  uchar *tmpG = new uchar[nbytes];
  uchar *tmpB = new uchar[nbytes];
  uchar *tmpA;
  if (saveAlpha)
    tmpA = new uchar[nbytes];


  QString voxelType = "RGB";
  if (saveAlpha) voxelType = "RGBA";
  
  //*** max 1Gb per slab
  int slabSize;
  slabSize = (1024*1024*1024)/(w*h);

  savePvlHeader(trimFile,
		d, w, h,
		voxelType,
		slabSize);			       

  VolumeFileManager rFileManager;
  VolumeFileManager gFileManager;
  VolumeFileManager bFileManager;
  VolumeFileManager aFileManager;

  QString pvlfile = trimFile;
  pvlfile.chop(6);

  QString rFilename = pvlfile + QString("red");
  QString gFilename = pvlfile + QString("green");
  QString bFilename = pvlfile + QString("blue");
  QString aFilename = pvlfile + QString("alpha");

  rFileManager.setBaseFilename(rFilename);
  rFileManager.setDepth(d);
  rFileManager.setWidth(w);
  rFileManager.setHeight(h);
  rFileManager.setVoxelType(0);
  rFileManager.setHeaderSize(13);
  rFileManager.setSlabSize(slabSize);
  rFileManager.createFile(true);
  rFileManager.createFile(true);

  gFileManager.setBaseFilename(gFilename);
  gFileManager.setDepth(d);
  gFileManager.setWidth(w);
  gFileManager.setHeight(h);
  gFileManager.setVoxelType(0);
  gFileManager.setHeaderSize(13);
  gFileManager.setSlabSize(slabSize);
  gFileManager.createFile(true);
  gFileManager.createFile(true);

  bFileManager.setBaseFilename(bFilename);
  bFileManager.setDepth(d);
  bFileManager.setWidth(w);
  bFileManager.setHeight(h);
  bFileManager.setVoxelType(0);
  bFileManager.setHeaderSize(13);
  bFileManager.setSlabSize(slabSize);
  bFileManager.createFile(true);
  bFileManager.createFile(true);

  if (saveAlpha)
    {
      aFileManager.setBaseFilename(aFilename);
      aFileManager.setDepth(d);
      aFileManager.setWidth(w);
      aFileManager.setHeight(h);
      aFileManager.setVoxelType(0);
      aFileManager.setHeaderSize(13);
      aFileManager.setSlabSize(slabSize);
      aFileManager.createFile(true);
      aFileManager.createFile(true);
    }


  for(int i=dmax; i>=dmin; i--)
    {

      QImage imgL = QImage(m_imageList[i]);
      if (imgL.format() != QImage::Format_ARGB32)
	imgL = imgL.convertToFormat(QImage::Format_ARGB32);
      
      uchar *imgbits = imgL.bits();
      for(uint j=0; j<m_width*m_height; j++)
	{
	  tmpR[j] = imgbits[4*j+2];
	  tmpG[j] = imgbits[4*j+1];
	  tmpB[j] = imgbits[4*j+0];
	}

      if (saveAlpha)
	{
	  for(uint j=0; j<m_width*m_height; j++)
	    tmpA[j] = imgbits[4*j+3];
	}

      for(uint j=wmin; j<=wmax; j++)
	memcpy(tmpR+(j-wmin)*h,
	       tmpR+(j*nZ + hmin),
	       h);

      for(uint j=wmin; j<=wmax; j++)
	memcpy(tmpG+(j-wmin)*h,
	       tmpG+(j*nZ + hmin),
	       h);

      for(uint j=wmin; j<=wmax; j++)
	memcpy(tmpB+(j-wmin)*h,
	       tmpB+(j*nZ + hmin),
	       h);

      if (saveAlpha)
	{
	  for(uint j=wmin; j<=wmax; j++)
	    memcpy(tmpA+(j-wmin)*h,
		   tmpA+(j*nZ + hmin),
		   h);
	}

      rFileManager.setSlice(dmax-i, tmpR);
      gFileManager.setSlice(dmax-i, tmpG);
      bFileManager.setSlice(dmax-i, tmpB);
      if (saveAlpha)
	aFileManager.setSlice(dmax-i, tmpA);

      progress.setValue((int)(100*(float)(dmax-i)/(float)d));
      qApp->processEvents();
    }


  delete [] tmpR;
  delete [] tmpG;
  delete [] tmpB;

  if (saveAlpha)
    delete [] tmpA;

  progress.setValue(100);
}