void CImageTest::testCopy() { shared_ptr<CImage> pImage(new CImage("Data/Images/Test.jpg")); shared_ptr<CImage> pOtherImage(new CImage("Data/Images/Test.jpg")); // Check CPPUNIT_ASSERT(1 == pImage.use_count()); { // test that the copy ctor increments use_count shared_ptr<CImage> pImageCopy(pImage); CPPUNIT_ASSERT(2 == pImage.use_count()); // test equality CPPUNIT_ASSERT(pImageCopy == pImage); } // test that the dtor decrements use_count CPPUNIT_ASSERT(1 == pImage.use_count()); shared_ptr<CImage> pImageCopy(pImage); CPPUNIT_ASSERT(2 == pImage.use_count()); CPPUNIT_ASSERT(1 == pOtherImage.use_count()); pImageCopy = pOtherImage; // test that the assignment operator decrements the old value and increments the new one CPPUNIT_ASSERT(1 == pImage.use_count()); CPPUNIT_ASSERT(2 == pOtherImage.use_count()); // test equality CPPUNIT_ASSERT(pImageCopy == pOtherImage); }
void Color2Grayscale::pushImage(const ImageMeasurement& m ) { IplImage* img = *m; if(img->nChannels == 1) { LOG4CPP_DEBUG( logger, "Got grayscale image: pushing unmodified" ); m_outPort.send( m ); // TODO: why should we clone the image instead of just pushing the measurement? //boost::shared_ptr< Image > pImage(new Image(cvCloneImage(img))); //m_outPort.send( ImageMeasurement( m.time(), pImage ) ); } else { LOG4CPP_DEBUG( logger, "Got color image: pushing converted" ); boost::shared_ptr< Image > pImage( new Image( img->width, img->height, 1 ) ); pImage->origin = img->origin; //inserted by CW to have correct origin cvConvertImage(*m,*pImage); m_outPort.send( ImageMeasurement( m.time(), pImage ) ); } }
bool Object_content::Read(Environment &env, Stream &stream, Image::Format format) { Signal &sig = env.GetSignal(); int cntIcons = 0; do { IconDir iconDir; if (stream.Read(sig, &iconDir, IconDir::Size) < IconDir::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } cntIcons = Gura_UnpackUInt16(iconDir.idCount); } while (0); Int32List imageOffsets; for (int iIcon = 0; iIcon < cntIcons; iIcon++) { IconDirEntry iconDirEntry; if (stream.Read(sig, &iconDirEntry, IconDirEntry::Size) < IconDirEntry::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } long imageOffset = Gura_UnpackInt32(iconDirEntry.dwImageOffset); imageOffsets.push_back(imageOffset); } foreach (Int32List, pImageOffset, imageOffsets) { long imageOffset = *pImageOffset; if (!stream.Seek(sig, imageOffset, Stream::SeekSet)) return false; Image::BitmapInfoHeader bih; if (stream.Read(sig, &bih, Image::BitmapInfoHeader::Size) < Image::BitmapInfoHeader::Size) { sig.SetError(ERR_FormatError, "invalid ICO format"); return false; } int biWidth = Gura_UnpackInt32(bih.biWidth); int biHeight = Gura_UnpackInt32(bih.biHeight) / 2; UInt16 biBitCount = Gura_UnpackUInt16(bih.biBitCount); AutoPtr<Image> pImage(new Image(format)); if (!pImage->ReadDIBPalette(env, stream, biBitCount)) return false; if (!pImage->ReadDIB(sig, stream, biWidth, biHeight, biBitCount, true)) { return false; } _valList.push_back(Value(new Object_image(env, pImage.release()))); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QImage PoleFigureImageUtilities::Create3ImagePoleFigure(UInt8ArrayType* i0, UInt8ArrayType* i1, UInt8ArrayType* i2, PoleFigureConfiguration_t& config, int32_t layout) { // Create a QImage that is the width of the first 2 images and the height of the first and third QImage img0 = PoleFigureImageUtilities::CreateQImageFromRgbaArray(i0, config.imageDim, true); QImage img1 = PoleFigureImageUtilities::CreateQImageFromRgbaArray(i1, config.imageDim, true); QImage img2 = PoleFigureImageUtilities::CreateQImageFromRgbaArray(i2, config.imageDim, true); // Create the Scalar Bar image QImage scalarBar = PoleFigureImageUtilities::GenerateScalarBar(img0.width(), img0.height(), config); int pImageWidth = 0; int pImageHeight = 0; QPoint pos1; QPoint pos2; QPoint pos3; QPoint pos4; if(layout == SIMPL::Layout::Horizontal) { pImageWidth = img0.width() * 4; pImageHeight = img0.height(); pos1 = QPoint(0, 0); pos2 = QPoint(img0.width(), 0); pos3 = QPoint(img0.width() * 2, 0); pos4 = QPoint(img0.width() * 3, 0); } else if(layout == SIMPL::Layout::Vertical) { pImageWidth = img0.width(); pImageHeight = img0.height() * 4; pos1 = QPoint(0, 0); pos2 = QPoint(0, img0.height()); pos3 = QPoint(0, img0.height() * 2); pos4 = QPoint(0, img0.height() * 3); } else if(layout == SIMPL::Layout::Square) { pImageWidth = img0.width() + img1.width(); pImageHeight = img0.height() + img2.height(); pos1 = QPoint(0, 0); pos2 = QPoint(pImageWidth / 2, 0); pos3 = QPoint(0, pImageHeight / 2); pos4 = QPoint(pImageWidth / 2, pImageHeight / 2); } QImage pImage(pImageWidth, pImageHeight, QImage::Format_ARGB32_Premultiplied); pImage.fill(0xFFFFFFFF); // All white background // Create a Painter backed by a QImage to draw into QPainter painter; painter.begin(&pImage); painter.setRenderHint(QPainter::Antialiasing, true); painter.drawImage(pos1, img0); // Draw the first image in the upper Left painter.drawImage(pos2, img1); // Draw the second image in the upper right painter.drawImage(pos3, img2); // Draw the third image in the lower Left painter.drawImage(pos4, scalarBar); // Draw the Scalar Bar painter.end(); // Scale the image down to 225 pixels return pImage; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QImage PoleFigureImageUtilities::PaintPoleFigureOverlay(int imageWidth, int imageHeight, QString label, QImage image) { int pxHigh = 0; int pxWide = 0; // Scale the Font Point size to something reasonable to the size of the image. Here our standard was 14Pt Font when the // Pole figure was 512 Pixels square. int fontPtSize = imageHeight / 32; QFont font("Ariel", fontPtSize, QFont::Bold); QFontMetrics metrics(font); pxHigh = metrics.height(); pxWide = metrics.width(QString("Y")); int pxOffset = 2 * pxWide; int pyOffset = 2 * pxHigh; int pImageWidth = imageWidth + pxOffset * 2; int pImageHeight = imageHeight + pyOffset * 2; QImage pImage(pImageWidth, pImageHeight, QImage::Format_ARGB32_Premultiplied); pImage.fill(0xFFFFFFFF); // All white background // Create a Painter backed by a QImage to draw into QPainter painter; painter.begin(&pImage); painter.setRenderHint(QPainter::Antialiasing, true); qint32 penWidth = 1; #if 0 // DRAW A BORDER AROUND THE IMAGE FOR DEBUGGING QColor c(RgbColor::dRgb(255, 0, 0, 255)); painter.setPen(QPen(c, penWidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); painter.drawLine(0, 0, pImageWidth, 0); // Top painter.drawLine(0, 0, 0, pImageHeight); // Left painter.drawLine(pImageWidth, 0, pImageWidth, pImageHeight); // Right painter.drawLine(0, pImageHeight, pImageWidth, pImageHeight); // Bottom //----------------- #endif painter.setFont(font); // metrics = painter.fontMetrics(); // pxHigh = metrics.height(); // pxWide = metrics.width(QString("Y")); // Draw the Pole Figure into the center of the canvas QPoint point(pxOffset, pyOffset); painter.drawImage(point, image); // Scale pen width based on the size of the image penWidth = imageHeight / 256; painter.setPen(QPen(QColor(0, 0, 0, 255), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // Draw the Outer circular border around the pole figure QPainterPath circle; QPointF center(pImageWidth / 2, pImageHeight / 2); circle.addEllipse(center, imageWidth / 2, imageHeight / 2); painter.drawPath(circle); // Label the X Axis painter.drawText(pImageWidth - (pxWide * 1.5), pImageHeight / 2 + pxHigh / 3, "X"); // Label the Y Axis pxWide = metrics.width(QString("Y")); painter.drawText(pImageWidth / 2 - pxWide / 2, pyOffset - penWidth - 1, "Y"); // Draw the name of the Pole Figure int labelWidth = 0; int maxWidth = pImageWidth / 5; // No more than a Quarter of the width of the image while(labelWidth < maxWidth) { fontPtSize++; font = QFont("Ariel", fontPtSize, QFont::Bold); metrics = QFontMetrics(font); labelWidth = metrics.width(label); // Figure out which string is longer (pixel wise) } painter.setFont(font); pxHigh = metrics.height() + 2; // pxWide = metrics.width(label); painter.drawText(pxOffset, pxHigh, label); // Draw slightly transparent lines //penWidth = 1; painter.setPen(QPen(QColor(0, 0, 0, 180), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // Draw the X Axis painter.drawLine(pxOffset, pImageHeight / 2, pImageWidth - pxOffset, pImageHeight / 2); // Draw the Y Axis painter.drawLine(pImageWidth / 2, pyOffset, pImageWidth / 2, pImageHeight - pyOffset); painter.end(); return pImage; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QImage PoleFigureImageUtilities::GenerateScalarBar(int imageWidth, int imageHeight, PoleFigureConfiguration_t& config) { int numColors = config.numColors; QImage pImage(imageWidth, imageHeight, QImage::Format_ARGB32_Premultiplied); pImage.fill(0xFFFFFFFF); // All white background // Create a Painter backed by a QImage to draw into QPainter painter; painter.begin(&pImage); painter.setRenderHint(QPainter::Antialiasing, true); int penWidth = 1; #if 0 // DRAW A BORDER AROUND THE IMAGE FOR DEBUGGING QColor c(RgbColor::dRgb(255, 0, 0, 255)); painter.setPen(QPen(c, penWidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); painter.drawLine(0, 0, imageWidth, 0); // Top painter.drawLine(0, 0, 0, imageHeight); // Left painter.drawLine(imageWidth, 0, imageWidth, imageHeight); // Right painter.drawLine(0, imageHeight, imageWidth, imageHeight); // Bottom //----------------- #endif //Get all the colors that we will need QVector<SIMPL::Rgb> colorTable(numColors); QVector<float> colors(3 * numColors, 0.0); SIMPLColorTable::GetColorTable(numColors, colors); // Generate the color table values float r = 0.0, g = 0.0, b = 0.0; for (int i = 0; i < numColors; i++) // Convert them to QRgbColor values { r = colors[3 * i]; g = colors[3 * i + 1]; b = colors[3 * i + 2]; colorTable[i] = RgbColor::dRgb(r * 255, g * 255, b * 255, 255); } // Now start from the bottom and draw colored lines up the scale bar // A Slight Indentation for the scalar bar float margin = 0.05f; float scaleBarRelativeWidth = 0.10f; float scaleBarRelativeHeight = 1.0f - (margin * 2); int colorHeight = int( (imageHeight * scaleBarRelativeHeight) / numColors); QPointF topLeft(imageWidth * margin, imageHeight * margin); QSizeF size(imageWidth * scaleBarRelativeWidth, imageHeight * scaleBarRelativeHeight); int yLinePos = topLeft.y(); QPointF start = topLeft; QPointF end = topLeft; for(int i = numColors - 1; i >= 0; i--) { QColor c(colorTable[i]); painter.setPen(QPen(c, penWidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); for(int j = 0; j < colorHeight; j++) { start.setY(yLinePos); end.setX(topLeft.x() + (imageWidth * scaleBarRelativeWidth)); end.setY(yLinePos); painter.drawLine(start, end); yLinePos++; } } // Draw the border of the scale bar size = QSizeF(imageWidth * scaleBarRelativeWidth, numColors * colorHeight); // Add two pixel to the height so we don't over write part of the scale bar QRectF scaleBorder(topLeft, size); penWidth = 2; painter.setPen(QPen(QColor(0, 0, 0, 255), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.drawRect(scaleBorder); // Draw the Text Labels of the Scale Bar int startFontPtSize = 10; QFont font("Ariel", startFontPtSize, QFont::Bold); QFontMetrics metrics(font); int fontPixelsHeight = metrics.height(); while(fontPixelsHeight < colorHeight * 2) { startFontPtSize++; font = QFont("Ariel", startFontPtSize, QFont::Bold); metrics = QFontMetrics(font); fontPixelsHeight = metrics.height(); } painter.setFont(font); // Draw some more information to the right of the Scale Bar QString maxStr = QString::number(config.maxScale, 'f', 3); painter.drawText(topLeft.x() + (imageWidth * scaleBarRelativeWidth) + 10, topLeft.y() + fontPixelsHeight, maxStr); QString minStr = QString::number(config.minScale, 'f', 3); painter.drawText(topLeft.x() + (imageWidth * scaleBarRelativeWidth) + 10, topLeft.y() + size.height(), minStr); //------------------------------ // Draw some statistics for the pole figures startFontPtSize = 8; // Set it to a rather large point size so we can fit the text perfectly. Only an insanely large Polefigure would go past this size int labelWidth = 0; // Make sure the size of font we just picked will allow the string to NOT be clipped because the rendered // pixel width is past the right side of the image int endOfStringYPos = topLeft.x() + (imageWidth * scaleBarRelativeWidth) + 10 + labelWidth; while(endOfStringYPos < imageWidth) { startFontPtSize++; font = QFont("Ariel", startFontPtSize, QFont::Bold); metrics = QFontMetrics(font); QString label("Upper & Lower"); QString label2 = QString("Samples: ") + QString::number(config.eulers->getNumberOfTuples()); fontPixelsHeight = metrics.height(); // Update the font height int labelWidth = metrics.width(label); // Figure out which string is longer (pixel wise) if (labelWidth < metrics.width(label2)) { labelWidth = metrics.width(label2); } endOfStringYPos = topLeft.x() + (imageWidth * scaleBarRelativeWidth) + 10 + labelWidth; } startFontPtSize--; font = QFont("Ariel", startFontPtSize, QFont::Bold); metrics = QFontMetrics(font); QString label("Upper & Lower"); QString label2 = QString("Samples: ") + QString::number(config.eulers->getNumberOfTuples()); labelWidth = metrics.width(label); if (labelWidth < metrics.width(label2)) { labelWidth = metrics.width(label2); } // Set the font into the Painter painter.setFont(font); QPointF statsPoint(topLeft.x() + (imageWidth * scaleBarRelativeWidth) + 10, imageHeight * .5); // Draw some more Statistics Text painter.drawText(statsPoint, label); statsPoint.setY(imageHeight * .5 + fontPixelsHeight); painter.drawText(statsPoint, label2); painter.end(); // Scale the image down to 225 pixels return pImage; }
void CImageTest::testFileNotFoundThrows() { shared_ptr<CImage> pImage(new CImage("NotAFile")); }
void CImageTest::testConstructor() { shared_ptr<CImage> pImage(new CImage("Data/Images/Test.jpg")); CPPUNIT_ASSERT(NULL != pImage); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QImage PoleFigureMaker::paintImage(int imageWidth, int imageHeight, QString label, QImage image) { int pxHigh = 0; int pxWide = 0; QFont font("Ariel", 16, QFont::Bold); { QPainter painter; QImage pImage(100, 100, QImage::Format_ARGB32_Premultiplied); pImage.fill(0xFFFFFFFF); // All white background painter.begin(&pImage); painter.setFont(font); QFontMetrics metrics = painter.fontMetrics(); pxHigh = metrics.height(); pxWide = metrics.width(QString("TD")); painter.end(); } int pxOffset = 2 * pxWide; int pyOffset = 2 * pxHigh; // Get a QPainter object to add some more details to the image int pImageWidth = imageWidth + pxOffset * 2; int pImageHeight = imageHeight + pyOffset * 2; QImage pImage(pImageWidth, pImageHeight, QImage::Format_ARGB32_Premultiplied); pImage.fill(0xFFFFFFFF); // All white background // Create a Painter backed by a QImage to draw into QPainter painter; painter.begin(&pImage); painter.setRenderHint(QPainter::Antialiasing, true); painter.setFont(font); QFontMetrics metrics = painter.fontMetrics(); pxHigh = metrics.height(); pxWide = metrics.width(QString("TD")); QPoint point(pxOffset, pyOffset); painter.drawImage(point, image); // Draw the image we just generated into the QPainter's canvas qint32 penWidth = 2; painter.setPen(QPen(QColor(0, 0, 0, 255), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QPainterPath circle; QPointF center(pImageWidth / 2, pImageHeight / 2); circle.addEllipse(center, imageWidth / 2, imageHeight / 2); painter.drawPath(circle); painter.drawText(pImageWidth - 2 * pxWide + 4, pImageHeight / 2 + pxHigh / 3, "TD"); pxWide = metrics.width(QString("RD")); painter.drawText(pImageWidth / 2 - pxWide / 2, pImageHeight - pyOffset + pxHigh + 2, "RD"); pxWide = metrics.width(label); painter.drawText(2, pxHigh, label); // Draw slightly transparent lines penWidth = 1; painter.setPen(QPen(QColor(0, 0, 0, 180), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.drawLine(pxOffset, pImageHeight / 2, pImageWidth - pxOffset, pImageHeight / 2); painter.drawLine(pImageWidth / 2, pyOffset, pImageWidth / 2, pImageHeight - pyOffset); painter.end(); // Scale the image down to 225 pixels return pImage;//.scaled(225, 225, Qt::KeepAspectRatio, Qt::SmoothTransformation); }
/// <summary> /// Get existing module or map it if absent /// </summary> /// <param name="path">Image path</param> /// <param name="buffer">Image data buffer</param> /// <param name="size">Buffer size.</param> /// <param name="asImage">If set to true - buffer has image memory layout</param> /// <param name="flags">Mapping flags</param> /// <returns>Module info</returns> const ModuleData* MMap::FindOrMapModule( const std::wstring& path, void* buffer, size_t size, bool asImage, eLoadFlags flags /*= NoFlags*/ ) { NTSTATUS status = STATUS_SUCCESS; std::unique_ptr<ImageContext> pImage(new ImageContext()); pImage->FilePath = path; pImage->FileName = Utils::StripPath(pImage->FilePath); pImage->flags = flags; // Load and parse image status = buffer ? pImage->peImage.Load(buffer, size, !asImage) : pImage->peImage.Load(path, flags & NoSxS ? true : false); if(!NT_SUCCESS(status)) { BLACBONE_TRACE(L"ManualMap: Failed to load image '%ls'/0x%p. Status 0x%X", path.c_str(), buffer, status); pImage->peImage.Release(); return nullptr; } // Check if already loaded if(auto hMod = _process.Modules().GetModule(path, LdrList, pImage->peImage.ImageType())) { pImage->peImage.Release(); return hMod; } BLACBONE_TRACE(L"ManualMap: Loading new image '%ls'", path.c_str()); // Try to map image in high (>4GB) memory range if(flags & MapInHighMem) { AllocateInHighMem(pImage->imgMem, pImage->peImage.ImageSize()); } // Try to map image at it's original ASRL-aware base else if(flags & HideVAD) { ptr_t base = pImage->peImage.ImageBase(); ptr_t isize = pImage->peImage.ImageSize(); if(!NT_SUCCESS(Driver().EnsureLoaded())) { pImage->peImage.Release(); return nullptr; } // Allocate as physical at desired base status = Driver().AllocateMem(_process.Id(), base, isize, MEM_COMMIT, PAGE_EXECUTE_READWRITE, true); // Allocate at any base if(!NT_SUCCESS(status)) { base = 0; size = pImage->peImage.ImageSize(); status = Driver().AllocateMem(_process.Id(), base, isize, MEM_COMMIT, PAGE_EXECUTE_READWRITE, true); } // Store allocated region if(NT_SUCCESS(status)) { pImage->imgMem = MemBlock(&_process.Memory(), base, static_cast<size_t>(isize), PAGE_EXECUTE_READWRITE, true, true); } // Stop mapping else { //flags &= ~HideVAD; BLACBONE_TRACE(L"ManualMap: Failed to allocate physical memory for image, status 0x%d", status); pImage->peImage.Release(); return nullptr; } } // Allocate normally if something went wrong if(pImage->imgMem == 0) pImage->imgMem = _process.Memory().Allocate(pImage->peImage.ImageSize(), PAGE_EXECUTE_READWRITE, pImage->peImage.ImageBase()); BLACBONE_TRACE(L"ManualMap: Image base allocated at 0x%p", pImage->imgMem.Ptr<size_t>()); if(!pImage->imgMem.Valid()) return nullptr; // Create Activation context for SxS if(pImage->peImage.ManifestID() == 0) flags |= NoSxS; if(!(flags & NoSxS)) CreateActx(pImage->peImage.ManifestFile(), pImage->peImage.ManifestID(), !pImage->peImage.NoPhysFile()); // Core image mapping operations if(!CopyImage(pImage.get()) || !RelocateImage(pImage.get())) { pImage->peImage.Release(); return nullptr; } auto mt = pImage->peImage.ImageType(); auto pMod = _process.Modules().AddManualModule(pImage->FilePath, pImage->imgMem.Ptr<module_t>(), pImage->imgMem.Size(), mt); // Import tables if(!ResolveImport(pImage.get()) || (!(flags & NoDelayLoad) && !ResolveImport(pImage.get(), true))) { pImage->peImage.Release(); _process.Modules().RemoveManualModule(pImage->FileName, mt); return nullptr; } // Apply proper memory protection for sections if(!(flags & HideVAD)) ProtectImageMemory(pImage.get()); // Make exception handling possible (C and C++) if(!(flags & NoExceptions)) { status = EnableExceptions(pImage.get()); if(!NT_SUCCESS(status) && status != STATUS_NOT_FOUND) { BLACBONE_TRACE(L"ManualMap: Failed to enable exception handling for image %ls", pImage->FileName.c_str()); pImage->peImage.Release(); _process.Modules().RemoveManualModule(pImage->FileName, mt); return nullptr; } } // Unlink image from VAD list if(flags & HideVAD && !NT_SUCCESS(ConcealVad(pImage->imgMem))) { pImage->peImage.Release(); _process.Modules().RemoveManualModule(pImage->FileName, mt); return nullptr; } // Initialize security cookie if(!InitializeCookie(pImage.get())) { pImage->peImage.Release(); _process.Modules().RemoveManualModule(pImage->FileName, mt); return nullptr; } // Get entry point pImage->EntryPoint = pImage->peImage.EntryPoint(pImage->imgMem.Ptr<ptr_t>()); // Create reference for native loader functions LdrRefFlags ldrFlags = flags & CreateLdrRef ? Ldr_All : Ldr_None; if(_mapCallback != nullptr) { auto mapData = _mapCallback(PostCallback, _userContext, _process, *pMod); ldrFlags = mapData.ldrFlags; } if(ldrFlags != Ldr_None) { _process.NativeLdr().CreateNTReference( pImage->imgMem.Ptr<HMODULE>(), pImage->peImage.ImageSize(), pImage->FilePath, static_cast<size_t>(pImage->EntryPoint), ldrFlags ); } // Static TLS data if(!(flags & NoTLS) && !InitStaticTLS(pImage.get())) { pImage->peImage.Release(); _process.Modules().RemoveManualModule(pImage->FileName, mt); return nullptr; } // Fill TLS callbacks pImage->peImage.GetTLSCallbacks(pImage->imgMem.Ptr<ptr_t>(), pImage->tlsCallbacks); // Unload local copy pImage->peImage.Release(); // Release ownership of image memory block pImage->imgMem.Release(); // Store image _images.emplace_back(std::move(pImage)); return pMod; }
/// <summary> /// Get existing module or map it if absent /// </summary> /// <param name="path">Image path</param> /// <param name="flags">Mapping flags</param> /// <returns>Module info</returns> const ModuleData* MMap::FindOrMapModule( const std::wstring& path, int flags /*= NoFlags*/ ) { std::unique_ptr<ImageContext> pImage( new ImageContext() ); pImage->FilePath = path; pImage->FileName = Utils::StripPath( pImage->FilePath ); pImage->flags = static_cast<eLoadFlags>(flags); // Load and parse image if (!pImage->FileImage.Project( path ) || !pImage->PEImage.Parse( pImage->FileImage, pImage->FileImage.isPlainData() )) return nullptr; // Check if already loaded if (auto hMod = _process.modules().GetModule( path, LdrList, pImage->PEImage.mType() )) return hMod; // Try to map image in high memory range if (flags & MapInHighMem) { if (AllocateInHighMem( pImage->imgMem, pImage->PEImage.imageSize() ) == false) pImage->imgMem = _process.memory().Allocate( pImage->PEImage.imageSize( ), PAGE_EXECUTE_READWRITE, pImage->PEImage.imageBase() ); } // Try to map image at it's original ASRL-aware base else { pImage->imgMem = _process.memory().Allocate( pImage->PEImage.imageSize(), PAGE_EXECUTE_READWRITE, pImage->PEImage.imageBase() ); } if (!pImage->imgMem.valid()) return nullptr; // Create Activation context for SxS // .exe files usually contain manifest under id of 1 // .dll files have manifest under id of 2 if (!(flags & NoSxS)) CreateActx( path, pImage->FileImage.manifestID() ); // Manual Debug tests only /*if (!(flags & NoExceptions)) { MExcept::pImageBase = pImage->image.ptr<void*>( ); MExcept::imageSize = pImage->PEImage.imageSize( ); }*/ // Core image mapping operations if (!CopyImage( pImage.get() ) || !RelocateImage( pImage.get() )) return nullptr; auto mt = pImage->PEImage.mType(); auto pMod = _process.modules().AddManualModule( pImage->FilePath, pImage->imgMem.ptr<module_t>(), pImage->imgMem.size(), mt ); // Import tables if (!ResolveImport( pImage.get() ) || (!(flags & NoDelayLoad) && !ResolveImport( pImage.get(), true ))) { _process.modules().RemoveManualModule( pImage->FileName, mt ); return nullptr; } // Apply proper memory protection for sections ProtectImageMemory( pImage.get() ); // Make exception handling possible (C and C++) if (!(flags & NoExceptions) && !EnableExceptions( pImage.get() )) { _process.modules().RemoveManualModule( pImage->FileName, mt ); return nullptr; } // Unlink image from VAD list if (flags & UnlinkVAD) UnlinkVad( pImage->imgMem ); // Initialize security cookie if (!InitializeCookie( pImage.get() )) { _process.modules().RemoveManualModule( pImage->FileName, mt ); return nullptr; } // Create reference for native loader functions if (flags & CreateLdrRef) _process.nativeLdr().CreateNTReference( pImage->imgMem.ptr<HMODULE>(), pImage->PEImage.imageSize(), pImage->FilePath ); // Static TLS data if (!(flags & NoTLS) &&! InitStaticTLS( pImage.get( ) )) { _process.modules().RemoveManualModule( pImage->FileName, mt ); return nullptr; } // Fill TLS callbacks pImage->PEImage.GetTLSCallbacks( pImage->imgMem.ptr<ptr_t>(), pImage->tlsCallbacks ); // Get entry point pImage->EntryPoint = pImage->PEImage.entryPoint( pImage->imgMem.ptr<ptr_t>() ); // Unload local copy pImage->FileImage.Release(); // Release image pImage->imgMem.Release(); // Store image _images.emplace_back( std::move( pImage ) ); return pMod; }
HBITMAP g_load_png_gdiplus_throw(HDC dc, const char * fn, unsigned target_cx, unsigned target_cy) { //FIXME m_gdiplus_initialised = (Gdiplus::Ok == Gdiplus::GdiplusStartup(&m_gdiplus_instance, &Gdiplus::GdiplusStartupInput(), NULL)); pfc::string8 canPath; HBITMAP bm = 0; abort_callback_dummy p_abort; file::ptr p_file; filesystem::g_get_canonical_path(fn, canPath); filesystem::g_open_read(p_file, canPath, p_abort); t_size fsize = pfc::downcast_guarded<t_size>(p_file->get_size_ex(p_abort)); pfc::array_staticsize_t<t_uint8> buffer(fsize); p_file->read(buffer.get_ptr(), fsize, p_abort); p_file.release(); IStream *pStream = NULL; HGLOBAL gd = GlobalAlloc(GMEM_FIXED | GMEM_MOVEABLE, buffer.get_size()); if (gd == NULL) throw exception_win32(GetLastError()); void * p_data = GlobalLock(gd); if (p_data == NULL) { GlobalFree(gd); throw exception_win32(GetLastError()); } memcpy(p_data, buffer.get_ptr(), buffer.get_size()); GlobalUnlock(gd); HRESULT hr = CreateStreamOnHGlobal(gd, TRUE, &pStream); if (FAILED(hr)) { GlobalFree(gd); throw exception_win32(hr); } Gdiplus::Bitmap pImage(pStream); CheckGdiplusStatus() << pImage.GetLastStatus(); { Gdiplus::BitmapData bitmapData; //Gdiplus::Bitmap * ppImage = &pImage; if (target_cx != pfc_infinite || target_cy != pfc_infinite) { Gdiplus::Bitmap pBitmapResized(target_cx == pfc_infinite ? pImage.GetWidth() : target_cx, target_cy == pfc_infinite ? pImage.GetHeight() : target_cy, PixelFormat32bppARGB); CheckGdiplusStatus() << pBitmapResized.GetLastStatus(); Gdiplus::Graphics pGraphics(&pBitmapResized); CheckGdiplusStatus() << pGraphics.GetLastStatus(); CheckGdiplusStatus() << pGraphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); CheckGdiplusStatus() << pGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic); Gdiplus::ImageAttributes imageAttributes; CheckGdiplusStatus() << imageAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); CheckGdiplusStatus() << pGraphics.DrawImage(&pImage, Gdiplus::Rect(0, 0, pBitmapResized.GetWidth(), pBitmapResized.GetHeight()), 0, 0, pImage.GetWidth(), pImage.GetHeight(), Gdiplus::UnitPixel, &imageAttributes); CheckGdiplusStatus() << pBitmapResized.LockBits(&Gdiplus::Rect(0, 0, pBitmapResized.GetWidth(), pBitmapResized.GetHeight()), Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &bitmapData); bm = g_CreateHbitmapFromGdiplusBitmapData32bpp(bitmapData); CheckGdiplusStatus() << pBitmapResized.UnlockBits(&bitmapData); } else { CheckGdiplusStatus() << pImage.LockBits(&Gdiplus::Rect(0, 0, pImage.GetWidth(), pImage.GetHeight()), Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &bitmapData); //assert bitmapData.Stride == bitmapData.Width bm = g_CreateHbitmapFromGdiplusBitmapData32bpp(bitmapData); CheckGdiplusStatus() << pImage.UnlockBits(&bitmapData); } } return bm; }
//---------------------------------------------------------------------------- int ExtractRidges::Main (int, char**) { std::string imageName = Environment::GetPathR("Head.im"); ImageDouble2D image(imageName.c_str()); // Normalize the image values to be in [0,1]. int quantity = image.GetQuantity(); double minValue = image[0], maxValue = minValue; int i; for (i = 1; i < quantity; ++i) { if (image[i] < minValue) { minValue = image[i]; } else if (image[i] > maxValue) { maxValue = image[i]; } } double invRange = 1.0/(maxValue - minValue); for (i = 0; i < quantity; ++i) { image[i] = (image[i] - minValue)*invRange; } // Use first-order centered finite differences to estimate the image // derivatives. The gradient is DF = (df/dx, df/dy) and the Hessian // is D^2F = {{d^2f/dx^2, d^2f/dxdy}, {d^2f/dydx, d^2f/dy^2}}. int xBound = image.GetBound(0); int yBound = image.GetBound(1); int xBoundM1 = xBound - 1; int yBoundM1 = yBound - 1; ImageDouble2D dx(xBound, yBound); ImageDouble2D dy(xBound, yBound); ImageDouble2D dxx(xBound, yBound); ImageDouble2D dxy(xBound, yBound); ImageDouble2D dyy(xBound, yBound); int x, y; for (y = 1; y < yBoundM1; ++y) { for (x = 1; x < xBoundM1; ++x) { dx(x, y) = 0.5*(image(x+1, y) - image(x-1, y)); dy(x, y) = 0.5*(image(x, y+1) - image(x, y-1)); dxx(x, y) = image(x+1, y) - 2.0*image(x, y) + image(x-1, y); dxy(x, y) = 0.25*(image(x+1, y+1) + image(x-1, y-1) - image(x+1, y-1) - image(x-1, y+1)); dyy(x, y) = image(x, y+1) - 2.0*image(x, y) + image(x, y+1); } } dx.Save("dx.im"); dy.Save("dy.im"); dxx.Save("dxx.im"); dxy.Save("dxy.im"); dyy.Save("dyy.im"); // The eigensolver produces eigenvalues a and b and corresponding // eigenvectors U and V: D^2F*U = a*U, D^2F*V = b*V. Define // P = Dot(U,DF) and Q = Dot(V,DF). The classification is as follows. // ridge: P = 0 with a < 0 // valley: Q = 0 with b > 0 ImageDouble2D aImage(xBound, yBound); ImageDouble2D bImage(xBound, yBound); ImageDouble2D pImage(xBound, yBound); ImageDouble2D qImage(xBound, yBound); for (y = 1; y < yBoundM1; ++y) { for (x = 1; x < xBoundM1; ++x) { Vector2d gradient(dx(x, y), dy(x, y)); Matrix2d hessian(dxx(x, y), dxy(x, y), dxy(x, y), dyy(x, y)); EigenDecompositiond decomposer(hessian); decomposer.Solve(true); aImage(x,y) = decomposer.GetEigenvalue(0); bImage(x,y) = decomposer.GetEigenvalue(1); Vector2d u = decomposer.GetEigenvector2(0); Vector2d v = decomposer.GetEigenvector2(1); pImage(x,y) = u.Dot(gradient); qImage(x,y) = v.Dot(gradient); } } aImage.Save("a.im"); bImage.Save("b.im"); pImage.Save("p.im"); qImage.Save("q.im"); // Use a cheap classification of the pixels by testing for sign changes // between neighboring pixels. ImageRGB82D result(xBound, yBound); for (y = 1; y < yBoundM1; ++y) { for (x = 1; x < xBoundM1; ++x) { unsigned char gray = (unsigned char)(255.0f*image(x, y)); double pValue = pImage(x, y); bool isRidge = false; if (pValue*pImage(x-1 ,y) < 0.0 || pValue*pImage(x+1, y) < 0.0 || pValue*pImage(x, y-1) < 0.0 || pValue*pImage(x, y+1) < 0.0) { if (aImage(x, y) < 0.0) { isRidge = true; } } double qValue = qImage(x,y); bool isValley = false; if (qValue*qImage(x-1, y) < 0.0 || qValue*qImage(x+1, y) < 0.0 || qValue*qImage(x, y-1) < 0.0 || qValue*qImage(x, y+1) < 0.0) { if (bImage(x,y) > 0.0) { isValley = true; } } if (isRidge) { if (isValley) { result(x, y) = GetColor24(gray, 0, gray); } else { result(x, y) = GetColor24(gray, 0, 0); } } else if (isValley) { result(x, y) = GetColor24(0, 0, gray); } else { result(x, y) = GetColor24(gray, gray, gray); } } } result.Save("result.im"); return 0; }