返回顶部

收藏

剪贴板数据LZW压缩到文件及解压还原到剪贴板

更多

剪贴板数据LZW压缩到文件及解压还原到剪贴板

ClipCompressToFile.cpp

// ClipCompressToFile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ClipCompressToFile.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std; 
BYTE m_MaxBits = 9;
int m_TotalBits = 0;
DWORD m_SavedData = 0;
string strEncode;
struct dicElement
{
    DWORD   m_Prefix;       //  keep the prefix of the element
    BYTE    m_Letter;       //  keep the letter of the element

    dicElement()
    {
        m_Prefix = 0;
        m_Letter = 0;
    }
};
void GetBytesFromCode(CPtrArray *m_dictionary,CByteArray *Buffer, DWORD code)
{
    //  Fill an array with bytes using the code for retrieving 
    //  those bytes from the dictionary elements

    //  Since we dont have 0-255 in the dictionary we have to make 
    //  sure, that if we get below 256 we stop (but still add that code)
    //  Every code higher then 255, will have a letter attached to it,
    //  which we use for getting the string back.

    while (code > 255)
    {
        dicElement *tmpEl = (dicElement*)m_dictionary->GetAt(code - 256);
        Buffer->Add(tmpEl->m_Letter);
        code = tmpEl->m_Prefix;
        delete tmpEl;
    }
    Buffer->Add((BYTE)code);
}
void CompressData(CFile &dest,DWORD toSave)
{
    //  Move the data you want to write few bits to the left
    //  and combine it with the already existing data in the buffer
    m_SavedData |= toSave << (32 - m_MaxBits - m_TotalBits);
    //  Add the new added number of bits to the total bits counter
    m_TotalBits += m_MaxBits;
    //  Check if it's possible to enter the data to the file
    //  (over and equal a byte of data)
    while (m_TotalBits >= 8)
    {
        //  Get the byte we want to write
        DWORD writeData = m_SavedData;
        writeData >>= 24;
        dest.Write(&writeData, 1);
        //  remove the byte from the buffer
        m_SavedData <<= 8;
        //  Remove the byte from the counter
        m_TotalBits -= 8;
    }
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed") << endl;
        nRetCode = 1;
    }
    else
    {
        if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) //CF_UNICODETEXT
        {
            HGLOBAL hMem = GetClipboardData(CF_TEXT); 
            if (hMem != NULL) 
            {
                LPTSTR lpStr = (LPTSTR)GlobalLock(hMem); 
                if (lpStr != NULL)
                    GlobalUnlock(hMem);
                CFile targetFile;
                //  Open the dialog to select a file
                CFileDialog dlg(FALSE, "lzw", "Clipboard.lzw",OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY,"LZW压缩文件(*.lzw)|*.lzw||", NULL);
                //  Select a file to be opened
                if (dlg.DoModal() == IDCANCEL)
                    return 0;
                if (!targetFile.Open(dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate))
                    return 0;
                DWORD m_MaxCode[32]={0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,0x3FFF,0x7FFF,0xFFFF,0x1FFFF,0x3FFFF,0x7FFFF,0xFFFFF,0x1FFFFF,0x3FFFFF,0x7FFFFF,0xFFFFFF,0x1FFFFFF,0x3FFFFFF,0x7FFFFFF,0xFFFFFFF,0x1FFFFFFF,0x3FFFFFFF,0x7FFFFFFF};
                CPtrArray *m_dictionary= new CPtrArray;
                long result = 0;
                BYTE readByte = 0;
                CString logString;
                DWORD resAdd = 256;
                //  Get the total file size
                DWORD prefix=*lpStr++;
                //  Go over the rest of the file and read it
                while (readByte=*lpStr++)
                {
                    //  Check if the prefix and readByte combination exist in the dictionary
                    //  Returns the code of an element from the dictionary
                    //  by searching for the prefix and letter assosiated with
                    //  that element code.
                    //  Returns -1 if no entry was found
                    int total = m_dictionary->GetSize();
                    dicElement *temp = NULL;
                    for (int counter = 0; counter < total; counter++)
                    {
                        temp = (dicElement*)m_dictionary->GetAt(counter);
                        if ((temp->m_Prefix == prefix) && 
                            (temp->m_Letter == readByte))
                            break;
                        temp = NULL;
                    }
                    if (temp != NULL)
                        result =counter + 256;
                    else
                        result =-1;
                    //  If not exist
                    if (result == -1)
                    {
                        //  Add the new combination
                        //  Add a dictionary element.
                        //  Since the dictionary should already have all the values
                        //  between 0-255, we start it from 256.
                        dicElement *temp = new dicElement;
                        temp->m_Prefix = prefix;
                        temp->m_Letter = readByte;
                        m_dictionary->Add(temp);
                        resAdd = m_dictionary->GetSize() + 255;
                        //  Calculate the new bit size needed to encode the file
                        //  Check the value of the parameter against the Maximum number possible
                        //  and then returns the counter
                        //  This can also be acheived by right shifting the value until we get 0
                        //  and counting the number of times we doing it.
                        for (BYTE counter = 0; counter < 32; counter++)
                        {
                            if (resAdd <= m_MaxCode[counter])
                                break;
                        }
                        m_MaxBits = counter;
                        //  Since the minimal number of bits we are using is 9 (256 is the begining of the dictionary), 
                        //  then the minimal number of bits is check to return a 9 in case a lower value will be
                        //  reached in the application
                        if (m_MaxBits < 9)
                            m_MaxBits = 9;  
                        //  Send the prefix for compression in to the destination file
                        CompressData(targetFile, prefix);
                        //  Set the prefix as the readByte
                        prefix = readByte;
                        //  Initiate the result
                        result = -1;
                        delete temp;
                    }
                    else
                    {
                        //  Set the prefix as the result
                        prefix = result;
                        readByte = 0;
                    }
                }
                //  Insert to the file the maximum number of bit (for signaling the end of the
                //  compression\decompression)
                CompressData(targetFile, prefix);
                CompressData(targetFile, m_MaxCode[m_MaxBits]);
                //  Flash the rest of the file with 0
                CompressData(targetFile, 0);
                delete m_dictionary;
                targetFile.Flush();
                //  Close the files
                targetFile.Close();
            }
        }
    }

    return nRetCode;
}

FileDecompressToClip.cpp

// FileDecompressToClip.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "FileDecompressToClip.h"
#include <string>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;
string strDecode;
DWORD m_MaxCode[32]={0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,0x3FFF,0x7FFF,0xFFFF,0x1FFFF,0x3FFFF,0x7FFFF,0xFFFFF,0x1FFFFF,0x3FFFFF,0x7FFFFF,0xFFFFFF,0x1FFFFFF,0x3FFFFFF,0x7FFFFFF,0xFFFFFFF,0x1FFFFFFF,0x3FFFFFFF,0x7FFFFFFF};
BYTE m_MaxBits;
int m_TotalBits;
DWORD m_SavedData;
struct dicElement
{
    DWORD   m_Prefix;       //  keep the prefix of the element
    BYTE    m_Letter;       //  keep the letter of the element

    dicElement()
    {
        m_Prefix = 0;
        m_Letter = 0;
    }
};
void GetBytesFromCode(CPtrArray *m_dictionary,CByteArray *Buffer, DWORD code)
{
    //  Fill an array with bytes using the code for retrieving 
    //  those bytes from the dictionary elements

    //  Since we dont have 0-255 in the dictionary we have to make 
    //  sure, that if we get below 256 we stop (but still add that code)
    //  Every code higher then 255, will have a letter attached to it,
    //  which we use for getting the string back.
    dicElement *tmpEl = NULL;

    while (code > 255)
    {
        tmpEl = (dicElement*)m_dictionary->GetAt(code - 256);
        Buffer->Add(tmpEl->m_Letter);
        code = tmpEl->m_Prefix;
    }
    Buffer->Add((BYTE)code);
}

DWORD DecompressData(CFile &source)
{
    DWORD returnValue;
    BYTE readByte = 0;

    //  If the source file still contains information
    if (source.GetPosition() < source.GetLength())
    {
        //  check if the number of bits in the read buffer is >= 24
        while (m_TotalBits <= 24)
        {
            //  Read one byte
            source.Read(&readByte, 1);

            //  Add the byte to the read buffer
            m_SavedData |= (DWORD) readByte << (24 - m_TotalBits);
            //  Add byte to the bit counter
            m_TotalBits += 8;
        }
    }
    else
    {
        //  If there is no more data, and there are no more bits to read
        //  while the file is over, then return the maximum bit number
        //  to end the decompression process
        if (m_SavedData == 0 && m_TotalBits == 0)
            return m_MaxCode[m_MaxBits];
    }

    //  calculate the return information
    returnValue = m_SavedData >> (32 - m_MaxBits);
    //  Remove the returned information from the buffer
    m_SavedData <<= m_MaxBits;
    //  Remove the return information bit size from the bit counter
    m_TotalBits -= m_MaxBits;

    //  Return the data
    return returnValue;
}

BOOL Decompress(CFile &source)
{
    CPtrArray *m_dictionary= new CPtrArray;
    DWORD data = 0;
    CString logString;
    CByteArray decodeString;
    BYTE writeData = 0, character = 0;
    int counter = 0;

    m_SavedData = 0;
    m_TotalBits = 0;
    m_MaxBits = 9;

    //  Get the first prefix information
    DWORD prefix = DecompressData(source);
    //  Save the prefix as the last used character (since we're writing it in the
    //  destination file)
    character = (BYTE)prefix;
    //  Write the prefix in the destination file (the first byte inside
    //  a LZW copressed file is always the first byte of the original file)
    strDecode+=prefix;
    //  While the recieve data is not the maximum bit data possible
    while ((data = DecompressData(source)) != m_MaxCode[m_MaxBits])
    {
        //  Check if the code exist in the dictionary
        //  if not
        //  Check if the code exist in the dictionary
        //  Returns TRUE if so, and FALSE if not.

        //  If the code is lower then 256, then the element is a normal
        //  ASCII character, and as such is considered to be in the
        //  dictionay.
        if (data >= 256 && data - 256 >= (unsigned)m_dictionary->GetSize())
        {
            //  Get the last used character into the decod buffer
            decodeString.Add((BYTE)character);
            //  Decode the existing prefix into a known string of data
            GetBytesFromCode(m_dictionary,&decodeString, prefix);
        }
        else
        {
            //  Decode the data into the decode buffer
            GetBytesFromCode(m_dictionary,&decodeString, data);
            //  Get the last letter inside the data, as the last used letter
            character = decodeString.GetAt(decodeString.GetSize() - 1);
        }

        //  Go over the decode buffer, from the end to the start,
        //  and write the information into the destination file
        counter = decodeString.GetSize();
        while (counter > 0)
        {
            writeData = (BYTE)decodeString.GetAt(--counter);
            strDecode+=writeData;
            //  To show a log in the view
        }

        //  Clear the decode buffer
        decodeString.RemoveAll();
        //  Add the new combination into the dictionary
        //  Add a dictionary element.
        //  Since the dictionary should already have all the values
        //  between 0-255, we start it from 256.
        dicElement *tmp = new dicElement;

        tmp->m_Prefix = prefix;
        tmp->m_Letter = (BYTE)character;

        m_dictionary->Add(tmp);

        //  Calculate the new buffer size to read now
        DWORD value=m_dictionary->GetSize() + 257;
        //  Check the value of the parameter against the Maximum number possible
        //  and then returns the counter

        //  This can also be acheived by right shifting the value until we get 0
        //  and counting the number of times we doing it.

        for (BYTE counter = 0; counter < 32; counter++)
            if (value <= m_MaxCode[counter])
                break;
        m_MaxBits = counter;

        //  Since the minimal number of bits we are using is 9 (256 is the begining of the dictionary), 
        //  then the minimal number of bits is check to return a 9 in case a lower value will be
        //  reached in the application
        if (m_MaxBits < 9)
            m_MaxBits = 9;              
        //  Set the new prefix to use
        prefix = data;
        delete tmp;
    }
    delete m_dictionary;
    return TRUE;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed") << endl;
        nRetCode = 1;
    }
    else
    {
        if(OpenClipboard(NULL)) //if (!OpenClipboard(m_hWnd))
        {
            CFile sourceFile;
            //  Open the dialog to select a file
            CFileDialog cFD(TRUE, NULL, "Clipboard.lzw", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Compressed files (*.lzw)|*.lzw|");

            //  Select a file to be opened
            if (cFD.DoModal() == IDCANCEL)
                return 0;
            CString m_SourceFile = cFD.GetPathName();

            if (!sourceFile.Open(m_SourceFile, CFile::modeRead))
                return 0;

            //  Decompress the file
            Decompress(sourceFile);
            sourceFile.Close();
            HGLOBAL hMem;
            TCHAR *pMem;
            hMem = GlobalAlloc( GHND | GMEM_DDESHARE, strDecode.length()+1);
            if(hMem)
            {
                pMem = (TCHAR*)GlobalLock(hMem);
                strcpy(pMem,strDecode.c_str());
                GlobalUnlock(hMem);
                EmptyClipboard();
                SetClipboardData(CF_TEXT,hMem);
            }
            CloseClipboard();
        }
    }
    return nRetCode;
}

标签:c++

收藏

0人收藏

支持

0

反对

0

»更多 您可能感兴趣的代码
  1. 2017-07-23 12:42:20奇数魔方阵 by Kevin.
  2. 2017-07-18 14:15:24两种方法计算“算术表达式” by aiheng1988
  3. 2015-09-09 16:29:06将jpg转换为bmp格式的文件 by qqmmcc
  4. 2015-09-09 09:29:49可执行文件加密 by walker30
  5. 2015-09-08 18:42:46TCP端口占用查询 by 灵剑子
  6. 2015-09-08 14:16:34Luffar schack五子棋 by 蟋蟀哥
  7. 2015-09-08 10:39:34wav转mp3的程序 by 灵剑子
  8. 2015-09-05 16:54:59逐行搜索目录中的文件内容并输出到Excel by 蟋蟀哥
  9. 2015-09-03 20:10:15LZW+AES+Base64编码解码剪贴板文本 by 童学芬
  10. 2015-09-01 17:47:21猫里奥 by aiheng1988
  11. 2015-08-31 15:33:59模拟键盘操作发送字符串 by 千万不要郁闷

发表评论