void ImageProcessing::Process(const Scalar* greyscale_image, size_t w, size_t h, size_t pitch) { width = w; height = h; const size_t img_area = width * height; if (img_area > tI.size()) { AllocateImageData(img_area); } // Process image gradient<>(width, height, greyscale_image, &dI[0]); integral_image(width, height, greyscale_image, &intI[0] ); // Threshold image AdaptiveThreshold( width, height, greyscale_image, &intI[0], &tI[0], params.at_threshold, width / params.at_window_ratio, 20, (unsigned char)0, (unsigned char)255 ); // Label image (connected components) labels.clear(); Label(width, height, &tI[0], &lI[0], labels, params.black_on_white ? 0 : 255 ); }
//----------------------------------------------------------------------------- // Unserialization of image data //----------------------------------------------------------------------------- bool CVTFTexture::LoadImageData( CUtlBuffer &buf, const VTFFileHeader_t &header, int nSkipMipLevels ) { // Fix up the mip count + size based on how many mip levels we skip... if (nSkipMipLevels > 0) { Assert( m_nMipCount > nSkipMipLevels ); if (header.numMipLevels < nSkipMipLevels) { // NOTE: This can only happen with older format .vtf files Warning("Warning! Encountered old format VTF file; please rebuild it!\n"); return false; } ComputeMipLevelDimensions( nSkipMipLevels, &m_nWidth, &m_nHeight ); m_nMipCount -= nSkipMipLevels; } // read the texture image (including mipmaps if they are there and needed.) int iImageSize = ComputeFaceSize( ); iImageSize *= m_nFaceCount * m_nFrameCount; // For backwards compatibility, we don't read in the spheremap fallback on // older format .VTF files... int nFacesToRead = m_nFaceCount; if (IsCubeMap()) { if ((header.version[0] == 7) && (header.version[1] < 1)) nFacesToRead = 6; } // NOTE: We load the bits this way because we store the bits in memory // differently that the way they are stored on disk; we store on disk // differently so we can only load up // NOTE: The smallest mip levels are stored first!! AllocateImageData( iImageSize ); for (int iMip = m_nMipCount; --iMip >= 0; ) { // NOTE: This is for older versions... if (header.numMipLevels - nSkipMipLevels <= iMip) continue; int iMipSize = ComputeMipSize( iMip ); for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame) { for (int iFace = 0; iFace < nFacesToRead; ++iFace) { unsigned char *pMipBits = ImageData( iFrame, iFace, iMip ); buf.Get( pMipBits, iMipSize ); } } } return buf.IsValid(); }
//----------------------------------------------------------------------------- // Initialization //----------------------------------------------------------------------------- bool CVTFTexture::Init( int nWidth, int nHeight, ImageFormat fmt, int iFlags, int iFrameCount ) { if (iFlags & TEXTUREFLAGS_ENVMAP) { if (nWidth != nHeight) { Warning("Height and width must be equal for cubemaps!\n"); return false; } } if( !IsPowerOfTwo( nWidth ) || !IsPowerOfTwo( nHeight ) ) { Warning( "Image dimensions must be power of 2!\n" ); return false; } if (fmt == IMAGE_FORMAT_DEFAULT) fmt = IMAGE_FORMAT_RGBA8888; m_nWidth = nWidth; m_nHeight = nHeight; m_Format = fmt; m_nFlags = iFlags; m_nMipCount = ComputeMipCount(); m_nFrameCount = iFrameCount; m_nFaceCount = (iFlags & TEXTUREFLAGS_ENVMAP) ? CUBEMAP_FACE_COUNT : 1; // Need to do this because Shutdown deallocated the low-res image m_nLowResImageWidth = m_nLowResImageHeight = 0; // Allocate me some bits! int iMemorySize = ComputeTotalSize(); AllocateImageData( iMemorySize ); return true; }
//----------------------------------------------------------------------------- // Converts the texture's image format. Use IMAGE_FORMAT_DEFAULT // if you want to be able to use various tool functions below //----------------------------------------------------------------------------- void CVTFTexture::ConvertImageFormat( ImageFormat fmt, bool bNormalToDUDV ) { if ( !m_pImageData ) return; if (fmt == IMAGE_FORMAT_DEFAULT) fmt = IMAGE_FORMAT_RGBA8888; if( bNormalToDUDV && !( fmt == IMAGE_FORMAT_UV88 || fmt == IMAGE_FORMAT_UVWQ8888 ) ) { Assert( 0 ); return; } if (m_Format == fmt) return; // FIXME: Should this be re-written to not do an allocation? int iConvertedSize = ComputeTotalSize( fmt ); unsigned char *pConvertedImage = (unsigned char*)MemAllocScratch(iConvertedSize); for (int iMip = 0; iMip < m_nMipCount; ++iMip) { int nMipWidth, nMipHeight; ComputeMipLevelDimensions( iMip, &nMipWidth, &nMipHeight ); for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame) { for (int iFace = 0; iFace < m_nFaceCount; ++iFace) { unsigned char *pSrcData = ImageData( iFrame, iFace, iMip ); unsigned char *pDstData = pConvertedImage + GetImageOffset( iFrame, iFace, iMip, fmt ); if( bNormalToDUDV ) { if( fmt == IMAGE_FORMAT_UV88 ) { ImageLoader::ConvertNormalMapRGBA8888ToDUDVMapUV88( pSrcData, nMipWidth, nMipHeight, pDstData ); } else if( fmt == IMAGE_FORMAT_UVWQ8888 ) { ImageLoader::ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888( pSrcData, nMipWidth, nMipHeight, pDstData ); } else { Assert( 0 ); return; } } else { ImageLoader::ConvertImageFormat( pSrcData, m_Format, pDstData, fmt, nMipWidth, nMipHeight ); } } } } AllocateImageData(iConvertedSize); memcpy( m_pImageData, pConvertedImage, iConvertedSize ); m_Format = fmt; MemFreeScratch(); }
ImageProcessing::ImageProcessing(int maxWidth, int maxHeight) : width(maxWidth), height(maxHeight) { AllocateImageData(maxWidth*maxHeight); }