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(); }
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); }