⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagedata.cpp

📁 图像显示软件源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
ImageData.cpp : Implementation file for the CImageData class
written by PJ Arends
pja@telus.net

For updates check http://www.codeproject.com/tools/imageviewer.asp

-----------------------------------------------------------------------------
This code is provided as is, with no warranty as to it's suitability or usefulness
in any application in which it may be used.

This code may be used in any way you desire. This file may be redistributed by any
means as long as it is not sold for profit, and providing that this notice and the
author's name are included. Any modifications not made by the original author should
be clearly marked as such to remove any confusion between the original version and
any other versions.

If any bugs are found and fixed, a note to the author explaining the problem and
fix would be nice.
-----------------------------------------------------------------------------
****************************************************************************/


#include "stdafx.h"
#include "ImageViewerApp.h"
#include "ImageData.h"

#include "..\common files\pja_dc.h"

#include <shlwapi.h>

size_t CImageData::MemUsage = 0;

// default c'tor
CImageData::CImageData()
: pCriticalSection(NULL)
, pData(NULL)
, Bitmap(NULL)
, DataSize(0)
, BPP(0)
{
}

// copy c'tor
CImageData::CImageData(const CImageData &ImageData)
: pCriticalSection(NULL)
, pData(NULL)
, Bitmap(NULL)
, DataSize(0)
, BPP(0)
{
    *this = ImageData;
}

CImageData::CImageData(HBITMAP hBitmap, WORD Bits)
: pCriticalSection(NULL)
, pData(NULL)
, Bitmap(NULL)
, DataSize(0)
, BPP(Bits)
{
    BITMAP bm;
    if (GetObject(hBitmap, sizeof(BITMAP), &bm))
    {
        pCriticalSection = new CCriticalSection;
        ULONG *pRef = new ULONG(1);
        pData = (LPBYTE)pRef;
        Bitmap = (HBITMAP)CopyImage(hBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
        DataSize = ((bm.bmWidth * bm.bmBitsPixel +31) & (~31)) / 8 * bm.bmHeight;

        MemUsage += GetSize();
    }
}

// d'tor
CImageData::~CImageData()
{
    DeleteData();
}

// copy the data from another CImageData object
CImageData& CImageData::operator =(const CImageData &ImageData)
{
    DeleteData();

    if (NULL != ImageData.pCriticalSection)
    {
        CSingleLock(ImageData.pCriticalSection, TRUE);
        if (NULL != ImageData.pData)
        {
            pData = ImageData.pData;
            DataSize = ImageData.DataSize;
            pCriticalSection = ImageData.pCriticalSection;
            Bitmap = ImageData.Bitmap;
            BPP = ImageData.BPP;

            IncrementReferenceCount();
        }
    }

    return *this;
}

// Get the data that was sent from the ImageViewer.dll.
// See CRecieverWindow::OnCopyData() and see the SendBitmapToViewer()
// function in the Viewer Library project.
bool CImageData::CopyData(const size_t &Size, LPBYTE Data)
{
    ASSERT (Size > 0);
    ASSERT (NULL != Data);

    bool ret = false;

    if (WAIT_OBJECT_0 != WaitForSingleObject(theApp.MemoryEvent, 0))
    {
        // out of memory, we cannot copy the image data
        return ret;
    }

    DeleteData();

    if (0 >= Size || NULL == Data)
    {
        return ret;
    }

    try
    {
        DataSize = Size;
        pData = new BYTE[sizeof(ULONG) + DataSize];                 // Include space for a reference counter
        pCriticalSection = new CCriticalSection;

        *reinterpret_cast<PULONG>(pData) = 0;                       // Set the reference counter to zero
        if (memcpy_s(pData + sizeof(ULONG), Size, Data, Size) == 0) // copy the image data into the buffer
        {
            ret = true;
            IncrementReferenceCount();
        }
    }
    catch (CMemoryException *me)
    {
        theApp.m_pMainWnd->PostMessage(WM_SETMESSAGESTRING, IDS_OUTOFMEMORY, 0);
        theApp.MemoryEvent.ResetEvent();
        TRACE("\n***************************  Out of Memory  *****************************\n\n");
        me->ReportError();
        me->Delete();
        ret = false;
    }

    if (!ret)
    {
        // unable to copy data, clean up
        delete[] pData;
        pData = NULL;
        DataSize = 0;

        delete pCriticalSection;
        pCriticalSection = NULL;
    }

    if (ret)
    {
        MemUsage += GetSize();
        if (MemUsage / 1024 >= theApp.MaximumMemoryUsage)
        {
            theApp.m_pMainWnd->PostMessage(WM_SETMESSAGESTRING, IDS_OUTOFMEMORY, 0);
            theApp.MemoryEvent.ResetEvent();
            TRACE(_T("Viewer Application - CImageData::OnCopyData: Memory limit reached\n"));
        }
    }

    return ret;
}

// cleanup
void CImageData::DeleteData()
{
    if (NULL != pCriticalSection)
    {
        CSingleLock SingleLock(pCriticalSection, TRUE);

        if (NULL != pData)
        {
            PULONG pReferenceCounter = reinterpret_cast<PULONG>(pData);
            --*pReferenceCounter;
            if (0 == *pReferenceCounter)
            {
                delete[] pData;
                SingleLock.Unlock();
                delete pCriticalSection;

                if (NULL != Bitmap)
                {
                    DeleteObject(Bitmap);
                }

                MemUsage -= GetSize();
            }
        }
    }

    pData = NULL;
    DataSize = 0;
    pCriticalSection = NULL;
    Bitmap = NULL;
    BPP = 0;
}

// increase the reference counter
void CImageData::IncrementReferenceCount()
{
    if (NULL != pCriticalSection)
    {
        CSingleLock SingleLock(pCriticalSection, TRUE);
        if (NULL != pData)
        {
            ++*reinterpret_cast<PULONG>(pData);
        }
    }
}

DWORD CImageData::GetProcessID() const
{
    DWORD ProcessID = 0;

    if (NULL == Bitmap && NULL != pCriticalSection)
    {
        CSingleLock SingleLock(pCriticalSection, TRUE);
        if (NULL != pData)
        {
            ProcessID = *reinterpret_cast<DWORD *>(pData + sizeof(ULONG));      // ProcessID is the first DWORD after the reference counter
        }
    }

    return ProcessID;
}

RECT CImageData::GetRegionRect() const
{
    RECT RegionRect = {0};

    if (NULL == Bitmap && NULL != pCriticalSection)
    {
        CSingleLock SingleLock(pCriticalSection, TRUE);

        if (NULL != pData)
        {
            // RegionRect will be empty if there is no region in this image
            LPBYTE ptr = pData + sizeof(ULONG) + sizeof(DWORD);                 // Skip over the reference counter and the processID
            LPRECT Rect = reinterpret_cast<LPRECT>(ptr);                        // Get the region rectangle
            memcpy_s(&RegionRect, sizeof(RECT), Rect, sizeof(RECT));
        }
    }

    return RegionRect;
}



std::tstring CImageData::GetSourceFilePath() const
{
    std::tstring ret;

    if (NULL == Bitmap && NULL != pCriticalSection)
    {
        CSingleLock SingleLock(pCriticalSection, TRUE);

        if (NULL != pData)
        {
            LPBYTE ptr = pData + sizeof(ULONG) + sizeof(DWORD) + sizeof(RECT);  // Skip over the reference counter, ProcessID and the region rectangle
            std::wstring Text = reinterpret_cast<LPWSTR>(ptr);                  // Get the text
            std::wstring::size_type end = Text.find(L"\n");                     // The file path is the first line

            ret = CW2CT(Text.substr(0, end).c_str());
        }
    }

    return ret;
}

std::tstring CImageData::GetSourceFile() const
{
    TCHAR Buffer[_MAX_PATH] = {0};
    _tcscpy_s(Buffer, _MAX_PATH, GetSourceFilePath().c_str());
    PathStripPath(Buffer);

    return std::tstring(Buffer);
}

std::tstring CImageData::GetSourcePath() const

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -