virtual void Paint(Draw &draw) { Rect paintrect=draw.GetPaintRect(); DDUMP(paintrect); Point p = paintrect.TopLeft(); if(p.x < ib.GetSize().cx && p.y < ib.GetSize().cy) SetSurface(draw, paintrect, ib, ib.GetSize(), p); }
/** * @brief * Apply effect to image */ bool IEScale::Apply(Image &cImage) const { // Are we allowed to use our mipmap trick? if (m_bUseMipmaps) { // Backup the given image Image cOriginalImage = cImage; // Loop through all image parts (for example for cube maps) bool bSuccess = true; for (uint32 nPart=0; nPart<cImage.GetNumOfParts() && bSuccess; nPart++) { // Get the image part ImagePart *pImagePart = cImage.GetPart(nPart); if (pImagePart) { // Scale all down via mipmap usage possible without predictable troubles? ImageBuffer *pImageBuffer = pImagePart->GetMipmap(0); if (pImageBuffer && pImageBuffer->GetSize() >= m_vNewSize) { // Loop through all available mipmaps while each MUST be smaller than the previous one // AND the formats MUST be the same (we just assume this, else this are totally invalid mipmaps!) while (bSuccess) { // Get the image buffer of the first mipmap pImageBuffer = pImagePart->GetMipmap(0); if (pImageBuffer) { // Is this the perfect mipmap for us? if (pImageBuffer->GetSize() == m_vNewSize) { // We're done, get us out of this loop right now! :D break; } else { // Throw away this mipmap pImagePart->DeleteMipmap(*pImageBuffer); } } else { bSuccess = false; } } } else { bSuccess = false; } } } // Success? if (bSuccess) return true; // Done // Restore the original image cImage = cOriginalImage; } // We have to scale in the classic and slow way... call the base implementation return ImageEffect::Apply(cImage); }
/** * @brief * Loads/reloads the sound */ void SNClipVolumeTexture::Load() { // Get/create a new volume resource instance (if there was a previous one, it will be destroyed by the manager as soon as no longer referenced) bool bNewCreated = false; Volume *pVolume = VolumeManager::GetInstance()->GetByName(m_sVolumeFilename); if (!pVolume) { pVolume = VolumeManager::GetInstance()->Create(m_sVolumeFilename); bNewCreated = true; } // Give our volume resource handler the new resource (it's possible that the previous volume resource is now going to be destroyed) m_pVolumeHandler->SetResource(pVolume); // [TODO] Handle varying loader parameters if (pVolume && bNewCreated) { // Setup volume if (pVolume) { // Load in the volume data if (pVolume->LoadByFilename(m_sVolumeFilename, LoaderParameters.Get())) { // [TODO] Check this situation when the loader parameters do not match // Try again without parameters? if (!pVolume->GetVolumeImage().GetBuffer()) pVolume->LoadByFilename(m_sVolumeFilename); // Create the texture buffer instance by using our image data SceneContext *pSceneContext = GetSceneContext(); if (pSceneContext) { // Get the renderer and renderer capabilities instance Renderer &cRenderer = pSceneContext->GetRendererContext().GetRenderer(); // [TODO] Just a test (volume image to texture buffer) TextureBuffer *pTextureBuffer = pVolume->GetVolumeTextureBuffer(cRenderer, !(GetFlags() & NoTextureCompression), !(GetFlags() & NoTextureMipmapping)); } } } } // Set the scale of the scene node? if (pVolume && !(GetFlags() & NoVolumeScale)) { // [TODO] Don't use the image data for this, may e.g. been unloaded within "GetVolumeTextureBuffer()" ImageBuffer *pImageBuffer = pVolume->GetVolumeImage().GetBuffer(); if (pImageBuffer) { // Get the size of one voxel (without metric, but usually one unit is equal to one meter) const Vector3 &vVoxelSize = pVolume->GetVoxelSize(); // Get the image size aka the number of voxels along each diagonal const Vector3i &vImageSize = pImageBuffer->GetSize(); // Set the scale of the scene node SetScale(Vector3(vVoxelSize.x*vImageSize.x, vVoxelSize.y*vImageSize.y, vVoxelSize.z*vImageSize.z)); } } }
/** * @brief * Constructor */ TextureBuffer2DArray::TextureBuffer2DArray(PLRenderer::Renderer &cRenderer, Image &cImage, EPixelFormat nInternalFormat, uint32 nFlags) : PLRenderer::TextureBuffer2DArray(cRenderer, nFlags) { // Update renderer statistics static_cast<PLRenderer::RendererBackend&>(cRenderer).GetWritableStatistics().nTextureBuffersNum++; // Get the image buffer ImageBuffer *pImageBuffer = cImage.GetBuffer(); if (pImageBuffer) { // Set data m_vSize = pImageBuffer->GetSize(); m_nFormat = (nInternalFormat == Unknown) ? GetFormatFromImage(cImage) : nInternalFormat; } }
bool ImageLoaderPVM::Save(const Image &cImage, File &cFile) { // Get image buffer, we only support the data type "byte" and "word" ImageBuffer *pImageBuffer = cImage.GetBuffer(); if (pImageBuffer && (pImageBuffer->GetDataFormat() == DataByte || pImageBuffer->GetDataFormat() == DataWord)) { // Save the data const Vector3i &vSize = pImageBuffer->GetSize(); writePVMvolume(cFile.GetUrl().GetNativePath().GetASCII(), pImageBuffer->GetData(), vSize.x, vSize.y, vSize.z, (pImageBuffer->GetDataFormat() == DataByte) ? 1 : 2); // Done return true; } // Error! return false; }
bool VolumeLoaderDAT::Save(const Volume &cVolume, File &cFile) { // Get the image holding the volumetric data const Image &cImage = cVolume.GetVolumeImage(); // Get image buffer, we only support the data type "byte" and "word" ImageBuffer *pImageBuffer = cImage.GetBuffer(); if (pImageBuffer && (pImageBuffer->GetDataFormat() == DataByte || pImageBuffer->GetDataFormat() == DataWord)) { const Vector3i &vSize = pImageBuffer->GetSize(); // Construct the object filename const String sObjectFilename = cFile.GetUrl().GetTitle() + ".raw"; // A "dat"-file has simple ASCII content cFile.PutS("ObjectFileName: " + sObjectFilename + '\n'); // Example: "ObjectFileName: Teddybear.raw" cFile.PutS("TaggedFileName: ---\n"); // Example: "TaggedFileName: ---" cFile.PutS("Resolution: " + vSize.ToString() + '\n'); // Example: "Resolution: 128 128 62" cFile.PutS("SliceThickness: 1 1 1\n"); // Example: "SliceThickness: 2.8 2.8 5" if (pImageBuffer->GetDataFormat() == DataByte) // Example: "Format: UCHAR" cFile.PutS("Format: UCHAR\n"); else cFile.PutS("Format: USHORT\n"); cFile.PutS("NbrTags: 0\n"); // Example: "NbrTags: 0" cFile.PutS("ObjectType: TEXTURE_VOLUME_OBJECT\n"); // Example: "ObjectType: TEXTURE_VOLUME_OBJECT" cFile.PutS("ObjectModel: RGBA\n"); // Example: "ObjectModel: RGBA" cFile.PutS("GridType: EQUIDISTANT\n"); // Example: "GridType: EQUIDISTANT" { // Raw data... // Get the absolute filename of the raw file const String sFilename = cFile.GetUrl().CutFilename() + sObjectFilename; // Open the raw file File cRawFile(sFilename); if (cRawFile.Open(File::FileCreate | File::FileWrite)) { // Save the data cRawFile.Write(pImageBuffer->GetData(), 1, pImageBuffer->GetDataSize()); // Done return true; } } } // Error! return false; }
//[-------------------------------------------------------] //[ Private virtual PLScene::SceneNode functions ] //[-------------------------------------------------------] void PGImage::InitFunction() { // Call base implementation SNParticleGroup::InitFunction(); // Load image Image cImage; if (cImage.LoadByFilename(ImageFilename.Get())) { // Get the image buffer ImageBuffer *pImageBuffer = cImage.GetBuffer(); if (pImageBuffer) { const uint32 nWidth = pImageBuffer->GetSize().x; const uint32 nHeight = pImageBuffer->GetSize().y; const uint32 nPixels = nWidth*nHeight; const uint8 *pData = pImageBuffer->GetData(); const uint32 nColorComponents = pImageBuffer->GetComponentsPerPixel(); if (nColorComponents == 3 || nColorComponents == 4) { // Get total number of required particles uint32 nParticles = 0; for (uint32 i=0; i<nPixels; i++) { // Place particle at this image position? uint8 nDifR = static_cast<uint8>(Math::Abs(pData[0]-RedColorKey)); uint8 nDifG = static_cast<uint8>(Math::Abs(pData[1]-GreenColorKey)); uint8 nDifB = static_cast<uint8>(Math::Abs(pData[2]-BlueColorKey)); if (!(nDifR <= ColorKeyTolerance && nDifG <= ColorKeyTolerance && nDifB <= ColorKeyTolerance)) nParticles++; // A particle here, please pData += nColorComponents; } pData = pImageBuffer->GetData(); // Create the particles InitParticles(nParticles); // Setup the particles for (int nY=nHeight-1; nY>=0; nY--) { for (uint32 nX=0; nX<nWidth; nX++) { // Place particle at this image position? uint8 nDifR = static_cast<uint8>(Math::Abs(pData[0]-RedColorKey)); uint8 nDifG = static_cast<uint8>(Math::Abs(pData[1]-GreenColorKey)); uint8 nDifB = static_cast<uint8>(Math::Abs(pData[2]-BlueColorKey)); if (nDifR <= ColorKeyTolerance && nDifG <= ColorKeyTolerance && nDifB <= ColorKeyTolerance) { // No particle here, please pData += nColorComponents; } else { // Setup particle Particle *pParticle = AddParticle(); if (pParticle) { pParticle->vColor.r = pData[0]/255.0f; pParticle->vColor.g = pData[1]/255.0f; pParticle->vColor.b = pData[2]/255.0f; pParticle->vColor.a = nColorComponents == 4 ? pData[3]/255.0f : 1.0f; pData += nColorComponents; pParticle->fEnergy = 1.0f; pParticle->fCustom2 = 0.5f+Math::GetRandFloat()*2.0f; if (Math::GetRandFloat() > 0.5f) pParticle->fCustom2 = -pParticle->fCustom2; pParticle->fSize = (1.0f+(static_cast<float>(Math::GetRand() % 1000)/500))*ImageScale; pParticle->vPos.x = pParticle->vFixPos.x = pParticle->vDistortion.x = static_cast<float>(nX*ImageScale); pParticle->vPos.y = pParticle->vFixPos.y = pParticle->vDistortion.y = static_cast<float>(nY*ImageScale); pParticle->vPos.z = pParticle->vFixPos.z = pParticle->vDistortion.z = 0.0f; pParticle->fCustom1 = pParticle->fSize; pParticle->fCustom2 *= 2; } else { // Error! nY = nHeight; nX = nWidth; } } } } } } } }
bool ImageLoaderJPG::SaveParams(const Image &cImage, File &cFile, uint32 nQuality) { // Get the image buffer ImageBuffer *pImageBuffer = cImage.GetBuffer(); if (pImageBuffer && pImageBuffer->GetBytesPerRow()) { // We only support 1 or 3 byte per pixel component if (pImageBuffer->GetBytesPerPixelComponent() == 1 || pImageBuffer->GetBytesPerPixelComponent() == 3) { jpeg_compress_struct sInfo; jpeg_error_mgr sError; sInfo.err = jpeg_std_error(&sError); sInfo.err->error_exit = ExitErrorHandle; jpeg_create_compress(&sInfo); const int nComponents = pImageBuffer->GetComponentsPerPixel(); sInfo.in_color_space = (nComponents == 1)? JCS_GRAYSCALE : JCS_RGB; jpeg_set_defaults(&sInfo); sInfo.input_components = nComponents; sInfo.num_components = (nComponents == 1) ? 1 : 3; sInfo.image_width = pImageBuffer->GetSize().x; sInfo.image_height = pImageBuffer->GetSize().y; sInfo.data_precision = 8; sInfo.input_gamma = 1.0; // Set the user given parameter jpeg_set_quality(&sInfo, nQuality, FALSE); jpeg_write_init(&sInfo, &cFile); jpeg_start_compress(&sInfo, TRUE); // Is the input image RGBA? If so, we really need to throw away the alpha channel... if (nComponents == 4) { // Allocate memory for an converted output row uint8 *pOutputRow = new uint8[sInfo.image_width*sInfo.num_components]; // Write the data const uint8 *pCurrentImageData = pImageBuffer->GetData(); for (uint32 y=0; y<sInfo.image_height; y++) { // Convert the current row for (uint32 x=0; x<sInfo.image_width; x++) { const uint8 *pnPixelIn = &pCurrentImageData[x*4]; uint8 *pnPixelOut = &pOutputRow[x*3]; pnPixelOut[0] = pnPixelIn[0]; pnPixelOut[1] = pnPixelIn[1]; pnPixelOut[2] = pnPixelIn[2]; } // Write out the current row jpeg_write_scanlines(&sInfo, &pOutputRow, 1); // Next, please pCurrentImageData += pImageBuffer->GetBytesPerRow(); } // Free the allocated output row memory delete [] pOutputRow; } else { // Write the data uint8 *pCurrentImageData = pImageBuffer->GetData(); for (uint32 y=0; y<sInfo.image_height; y++) { jpeg_write_scanlines(&sInfo, &pCurrentImageData, 1); pCurrentImageData += pImageBuffer->GetBytesPerRow(); } } // Cleanup jpeg_finish_compress(&sInfo); jpeg_destroy_compress(&sInfo); // Done return true; } else { // Error: Unsupported number of bytes per pixel component } } else { // Error: Failed to get image buffer } // Error! return false; }
bool IEScale::Apply(ImageBuffer &cImageBuffer) const { // Get dimensions const uint32 nNewWidth = m_vNewSize.x; const uint32 nNewHeight = m_vNewSize.y; const uint32 nOldWidth = cImageBuffer.GetSize().x; const uint32 nOldHeight = cImageBuffer.GetSize().y; // [TODO] 3D support // [TODO] Currently we only support 'scale down' // New width and new height must be >0, ColorPalette as color format is not supported if (cImageBuffer.GetColorFormat() != ColorPalette && nNewWidth <= nOldWidth && nNewHeight <= nOldHeight && nNewWidth && nNewHeight) { // 3x3 filter matrix static const Matrix3x3 mFilter(0.1f, 0.5f, 0.1f, 0.5f, 1.0f, 0.5f, 0.1f, 0.5f, 0.1f); // Create the new image buffer ImageBuffer cOldImageBuffer = cImageBuffer; // [TODO] Currently compressing data is not implemented, yet cImageBuffer.CreateImage(cOldImageBuffer.GetDataFormat(), cOldImageBuffer.GetColorFormat(), Vector3i(nNewWidth, nNewHeight, 1)); // cImageBuffer.CreateImage(cOldImageBuffer.GetDataFormat(), cOldImageBuffer.GetColorFormat(), Vector3i(nNewWidth, nNewHeight, 1), cOldImageBuffer.GetCompression()); // Process data format dependent switch (cImageBuffer.GetDataFormat()) { case DataByte: { ScaleDownData<uint8> cScaleDownData(cOldImageBuffer, cImageBuffer, nNewWidth, nNewHeight, nOldWidth, nOldHeight, mFilter); break; } case DataWord: { ScaleDownData<uint16> cScaleDownData(cOldImageBuffer, cImageBuffer, nNewWidth, nNewHeight, nOldWidth, nOldHeight, mFilter); break; } case DataHalf: { ScaleDownHalfData(cOldImageBuffer, cImageBuffer, nNewWidth, nNewHeight, nOldWidth, nOldHeight, mFilter); break; } case DataFloat: { ScaleDownData<float> cScaleDownData(cOldImageBuffer, cImageBuffer, nNewWidth, nNewHeight, nOldWidth, nOldHeight, mFilter); break; } case DataDouble: { ScaleDownData<double> cScaleDownData(cOldImageBuffer, cImageBuffer, nNewWidth, nNewHeight, nOldWidth, nOldHeight, mFilter); break; } } // Done return true; } // Error! return false; }
void PaintImageBuffer(ImageBuffer& ib, const Painting& p, int mode) { PaintImageBuffer(ib, p, ib.GetSize(), Point(0, 0), mode); }