SbBool writeImage( const char* file, unsigned int offset, SbXipImage& image ) { #ifdef WIN32 //assuming everything is done using the bad backslashes... so we convert all forward slashes to those const char * fileLocal = XipReplaceChar(file, '/', '\\').getString(); #else //UNIX //assuming the other way around since we need forward slashes now... const char * fileLocal = XipReplaceChar(file, '\\', '/').getString(); #endif //WIN32 int r = 0; void* imageBufferPtr = image.refBufferPtr(); if( imageBufferPtr ) { SbString path = XipStrExpandEnv( fileLocal ); FILE* fs = fopen( path.getString(), "wb" ); if (!fs) return FALSE; fseek( fs, offset, SEEK_SET ); r = fwrite(imageBufferPtr, 1, image.bufferSize(), fs ); fclose( fs ); } image.unrefBufferPtr(); return (r == image.bufferSize()); }
void SoVolumeMetrics::calculateVolumeMetris() { SoXipDataImage* maskData = inputVolume.getValue(); if (!maskData || !maskData->get()) { SoDebugError::postInfo(__FILE__, "input volume data is NULL"); return; } SbXipImage* mask = maskData->get(); SbMatrix matMask = mask->getModelMatrix(); SbXipImageDimensions maskDimension = mask->getDimStored(); //decompose the model matrix SbVec3f colVector, rowVector, norVector, volPosition; colVector[0] = matMask[0][0]; colVector[1] = matMask[0][1]; colVector[2] = matMask[0][2]; rowVector[0] = matMask[1][0]; rowVector[1] = matMask[1][1]; rowVector[2] = matMask[1][2]; norVector[0] = matMask[2][0]; norVector[1] = matMask[2][1]; norVector[2] = matMask[2][2]; volPosition[0] = matMask[3][0]; volPosition[1] = matMask[3][1]; volPosition[2] = matMask[3][2]; float valSpacing[3]; valSpacing[0] = colVector.length() / (float)maskDimension[0]; valSpacing[1] = rowVector.length() / (float)maskDimension[1]; valSpacing[2] = norVector.length() / (float)maskDimension[2]; double volumeFactor = 0.001*valSpacing[0]*valSpacing[1]*valSpacing[2]; unsigned long volume=0, recist=0, who=0; int nSize = maskDimension[0] * maskDimension[1]; unsigned char* pMask = (unsigned char*)mask->refBufferPtr(); for (int k = 0; k < maskDimension[2]; k++) { unsigned char* pSlice = pMask + k * nSize; for (int j = 0; j < nSize; j++) { if (pSlice[j] != 0) volume++; } } _volume = (double)volume * volumeFactor; mask->unrefBufferPtr(); }
void SoXipImageOperation::evaluate() { try { // Reset output if( mMaskData ) { mMaskData->unref(); mMaskData = 0; } SO_ENGINE_OUTPUT( mask, SoXipSFDataImage, setValue(0) ); SoXipDataImage* maskData1 = mask1.getValue(); SoXipDataImage* maskData2 = mask2.getValue(); if( !maskData1 || !maskData1->get() ) { if( operation.getValue() == MASK_OR || operation.getValue() == MASK_NOR ) { SO_ENGINE_OUTPUT( mask, SoXipSFDataImage, setValue(maskData2) ); } return ; } else if( !maskData2 || !maskData2->get() ) { if( operation.getValue() == MASK_OR || operation.getValue() == MASK_NOR ) { SO_ENGINE_OUTPUT( mask, SoXipSFDataImage, setValue(maskData1) ); } return ; } SbXipImage* maskImage1 = maskData1->get(); SbXipImage* maskImage2 = maskData2->get(); if( maskImage1->getType() != SbXipImage::UNSIGNED_BYTE || maskImage2->getType() != SbXipImage::UNSIGNED_BYTE || maskImage1->getComponentLayoutType() != SbXipImage::PACKED_LUMINANCE || maskImage2->getComponentLayoutType() != SbXipImage::PACKED_LUMINANCE ) { SoDebugError::post( __FILE__, "SoXipImageOperation::evaluate(): image format not supported. \ Expect unsigned 8 bits packed image" ); return ; } SbXipImageDimensions dimensions = maskImage1->getDimStored(); if( maskImage2->getDimStored() != dimensions ) { SoDebugError::post( __FILE__, "SoXipImageOperation::evaluate(): input masks have different dimensions" ); return ; } // Allocate output mask SbXipImage* maskOut = new SbXipImage( dimensions, SbXipImage::UNSIGNED_BYTE, 8, 1, SbXipImage::SEPARATE, SbXipImage::PACKED_LUMINANCE, maskImage1->getModelMatrix() ); if( !maskOut ) { SoMemoryError::post( "SoXipImageOperation::evaluate(): output mask" ); return ; } unsigned char* mask1Ptr = (unsigned char *) maskImage1->refBufferPtr(); unsigned char* mask2Ptr = (unsigned char *) maskImage2->refBufferPtr(); unsigned char* maskOutPtr = (unsigned char *) maskOut->refBufferPtr(); { int lineLengthAllocated = maskImage1->getLineLengthAllocated(); int numCells = dimensions[2] * dimensions[1] * lineLengthAllocated; if( operation.getValue() == MASK_OR ) { for( int i = 0; i < numCells; ++ i ) *maskOutPtr ++ = *mask1Ptr ++ | *mask2Ptr ++; } else if( operation.getValue() == MASK_AND ) { for( int i = 0; i < numCells; ++ i ) *maskOutPtr ++ = *mask1Ptr ++ & *mask2Ptr ++; } else if( operation.getValue() == MASK_NOR ) { for( int i = 0; i < numCells; ++ i ) *maskOutPtr ++ = *mask1Ptr ++ ^ *mask2Ptr ++; } } maskImage1->unrefBufferPtr(); maskImage2->unrefBufferPtr(); maskOut->unrefBufferPtr(); mMaskData = new SoXipDataImage; if( !mMaskData ) { SoMemoryError::post( "SoXipImageOperation::evaluate(): output mask data" ); return ; } mMaskData->ref(); mMaskData->set( maskOut ); SO_ENGINE_OUTPUT( mask, SoXipSFDataImage, setValue(mMaskData) ); }
void SoXipComposeVec6::evaluate() { SO_ENGINE_OUTPUT(outVOI, SoMFInt32, setNum(6)); // intersection of plane and volume SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(0, xmin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(1, xmax.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(2, ymin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(3, ymax.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(4, zmin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(5, zmax.getValue()) ); // Reset outputs SO_ENGINE_OUTPUT( numSlices, SoSFShort, setValue(0) ); SO_ENGINE_OUTPUT( output, SoXipSFDataImage, setValue(0) ); SoXipDataImage* imageData = image.getValue(); if( mImageData != imageData ) { mImageData = image.getValue(); // Reset previous outputs mOutputs.setNum(0); if( mImageData ) { SbXipImage* image = mImageData->get(); if( !image ) return ; // Initialize outputs unsigned int numSlices = image->getDimStored()[2]; mOutputs.setNum( numSlices ); for( unsigned int i = 0; i < numSlices; ++ i ) mOutputs.set1Value( i, 0 ); } } if( imageData ) { SbXipImage* image = mImageData->get(); if( !image ) return ; SbXipImageDimensions dimensions = image->getDimStored(); SbXipImageDimensions sliceDimensions = dimensions; sliceDimensions[2] = 1; int sliceIndex = this->sliceIndex.getValue(); if( sliceIndex < 0 || sliceIndex >= dimensions[2] ) return ; if( mOutputs[sliceIndex] == 0 ) { // Compute the model matrix of the selected frame SbMatrix sliceModelMatrix = image->getModelMatrix(); sliceModelMatrix[2][0] /= dimensions[2]; sliceModelMatrix[2][1] /= dimensions[2]; sliceModelMatrix[2][2] /= dimensions[2]; sliceModelMatrix[3][0] += sliceIndex * sliceModelMatrix[2][0]; sliceModelMatrix[3][1] += sliceIndex * sliceModelMatrix[2][1]; sliceModelMatrix[3][2] += sliceIndex * sliceModelMatrix[2][2]; // Pointer to the selected slice char* imagePtr = (char *) image->refBufferPtr(); unsigned int cellSize; switch( image->getType() ) { case SbXipImage::UNSIGNED_BYTE: cellSize = sizeof(unsigned char); break ; case SbXipImage::BYTE: cellSize = sizeof(char); break ; case SbXipImage::UNSIGNED_SHORT: cellSize = sizeof(unsigned short); break ; case SbXipImage::SHORT: cellSize = sizeof(short); break ; case SbXipImage::UNSIGNED_INT: cellSize = sizeof(unsigned int); break ; case SbXipImage::INT: cellSize = sizeof(int); break ; case SbXipImage::FLOAT: cellSize = sizeof(float); break ; case SbXipImage::DOUBLE: cellSize = sizeof(double); break ; } void* slicePtr = imagePtr + cellSize * image->getComponents() * dimensions[0] * dimensions[1] * sliceIndex; SbXipImage* slice = new SbXipImage( sliceDimensions, image->getType(), image->getBitsStored(), slicePtr, image->getComponents(), image->getComponentType(), image->getComponentLayoutType(), sliceModelMatrix, image->getLineAlignment() ); image->unrefBufferPtr(); SoXipDataImage* output = new SoXipDataImage(); output->ref(); output->set( slice ); output->addRef( imageData ); mOutputs.set1Value( sliceIndex, output ); } SO_ENGINE_OUTPUT( output, SoXipSFDataImage, setValue(mOutputs[sliceIndex]) ); } }
void SoXipCPUMprRender::readyBuffers(SoState *state) { SbXipImageDimensions dim(0, 0, 0); SoXipDataImage *imgData = 0; SbXipImage *image = 0; // Volume imgData = volume.getValue(); dim = SbXipImageDimensions(0,0,0); if (imgData && (image = imgData->get())) { // If data has changed, update MPR if (imgData->getDataId() != mVolDataId) { mVolDataId = imgData->getDataId(); mUpdateFlag |= UPDATE_MPR; } if (mVolDataType != image->getType() || mVolBitsUsed != image->getBitsStored()) { mVolDataType = image->getType(); mVolBitsUsed = image->getBitsStored(); mMPRSize = SbVec2s(-1, -1); // force buffer resizing } mVolBuf = image->refBufferPtr(); dim = imgData->get()->getDimAllocated(); // If dimensions have changed, update Cache if (dim != mVolDim) { mVolDim = dim; mUpdateFlag |= UPDATE_MPRCACHE; } } else { mVolBuf = 0; mVolDim = dim; mVolDataId = 0; } // Transfer function LUT imgData = (SoXipDataImage *) SoXipLutElement::get(state); if (imgData && (image = imgData->get()) && image->getType() == SbXipImage::FLOAT && image->getComponentLayoutType() == SbXipImage::RGBA) { // If there was no LUT before, resize buffers if (!mLutBuf) mMPRSize = SbVec2s(-1, -1); mLutSize = image->getDimStored()[0]; mLutBuf = (float*) image->refBufferPtr(); // If data has changed, update MPR if (imgData->getDataId() != mLutDataId) { mLutDataId = imgData->getDataId(); mUpdateFlag |= UPDATE_MPR; } } else { // If there was a LUT before, force resizing if (mLutBuf) mMPRSize = SbVec2s(-1, -1); mLutBuf = 0; mLutSize = 0; mLutDataId = 0; } }
SbXipImage* SoXipLoadBMP::loadBMP(const char *fileName) { try { BMP bmp; bmp.ReadFromFile(fileName); int numBits = bmp.TellBitDepth(); int width = bmp.TellWidth(); int height = bmp.TellHeight(); int bitsStored = 8; int samplesPerPixel = 0; SbXipImage::ComponentType compType = SbXipImage::INTERLEAVED; SbXipImage::ComponentLayoutType compLayoutType = SbXipImage::RGB; if(numBits<=24) { samplesPerPixel = 3; compLayoutType = SbXipImage::RGB; } else if(numBits == 32) { samplesPerPixel = 4; compLayoutType = SbXipImage::RGBA; } SbVec3f pos(0, 0, 0); SbVec3f scale(width, height, 1); SbMatrix rotMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1); SbMatrix modelMatrix; modelMatrix.setScale(scale); //modelMatrix.setTransform(pos, SbRotation(rotMatrix), scale); SbXipImage *image = new SbXipImage(SbXipImageDimensions(width, height, 1), SbXipImageDimensions(width, height, 1), SbXipImage::UNSIGNED_BYTE, bitsStored, samplesPerPixel, compType, compLayoutType, modelMatrix); unsigned char *buffer = (unsigned char *) image->refBufferPtr(); if(numBits<=24) { for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { RGBApixel pixel = bmp.GetPixel(j,(height -1) - i ); buffer[3*i*width+3*j] = pixel.Red; buffer[3*i*width+3*j+1] = pixel.Green; buffer[3*i*width+3*j+2] = pixel.Blue; } } } else if(numBits == 32) { for(int i=0; i<height; i++) { for(int j=0; j<width; j++) { RGBApixel pixel = bmp.GetPixel(j, height-i); buffer[4*i*width+4*j] = pixel.Red; buffer[4*i*width+4*j+1] = pixel.Green; buffer[4*i*width+4*j+2] = pixel.Blue; buffer[4*i*width+4*j+3] = pixel.Alpha; } } } image->unrefBufferPtr(); return image; } catch(...) { SoDebugError::postInfo(__FILE__, "Exception loadBMP"); // Fix me need to delete allocated memory! return 0; } }