home *** CD-ROM | disk | FTP | other *** search
- /*
- * PECompact v2 LZMA CODEC
- * Copyright (C) 2004 Joergen Ibsen (www.ibsensoftware.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #define WIN32_LEAN_AND_MEAN
-
- #include <windows.h>
- #include <stdio.h>
-
- #include "codec.h"
- #include "decode.h"
- #include "decodef.h"
-
- #define LZMA_BASE_SIZE 1846
- #define LZMA_LIT_SIZE 768
-
- BOOL execute(const char *cmdline)
- {
- PROCESS_INFORMATION pinfo;
- STARTUPINFO sinfo = { sizeof(STARTUPINFO) };
- HANDLE hReadPipe, hWritePipe;
- BOOL bRet;
-
- GetStartupInfo(&sinfo);
-
- sinfo.dwFlags = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES;
- sinfo.wShowWindow = SW_HIDE;
-
- bRet = CreateProcess(NULL, (char *)cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
- &sinfo, &pinfo);
-
- if (!bRet) return FALSE;
-
- /* wait for process to terminate */
- WaitForSingleObject(pinfo.hProcess, INFINITE);
-
- /* close process handles to allow it to terminate */
- CloseHandle(pinfo.hProcess);
- CloseHandle(pinfo.hThread);
-
- return TRUE;
- }
-
- DWORD WINAPI Encode(LPVOID lpvSource, DWORD dwSize, LPVOID lpvDest,
- DWORD *pdwDestSize, DWORD dwLevel, PFNCodecCallback pCodecCallback)
- {
- DWORD dwDestSize;
- void *lpvWorkmem;
-
- if (pdwDestSize == NULL)
- {
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
- return PEC2_CODEC_ERROR_UNSPECIFIED;
- }
-
- /* check destination buffer is large enough */
- if (*pdwDestSize < (dwSize + dwSize/8 + 64))
- {
- *pdwDestSize = (dwSize + dwSize/8 + 64);
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
- return PEC2_CODEC_ERROR_INSUFFICIENT_BUFFER;
- }
-
- /* call callback to indicate start of encoding */
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ENCODE, 0, 0, dwSize);
-
- /* perform compression */
- {
- int lc, lp, pb;
- unsigned int lzmaInternalSize;
- unsigned char prop0;
- FILE *f;
-
- f = fopen("lzmacodec_temp.dat", "wb");
-
- if (f == NULL) return PEC2_CODEC_ERROR_UNSPECIFIED;
-
- fwrite(lpvSource, dwSize, 1, f);
-
- fclose(f);
-
- execute("lzma.exe e lzmacodec_temp.dat lzmacodec_temp.lzma -fb255 -lc4 -d24");
-
- remove("lzmacodec_temp.dat");
-
- fopen("lzmacodec_temp.lzma", "rb");
-
- if (f == NULL) return PEC2_CODEC_ERROR_UNSPECIFIED;
-
- fseek(f, 0, SEEK_END);
- dwDestSize = ftell(f);
- fseek(f, 0, SEEK_SET);
-
- fread(&prop0, 1, 1, f);
-
- fseek(f, 13, SEEK_SET);
-
- dwDestSize -= 13;
-
- fread((unsigned char *)lpvDest + 15, dwDestSize, 1, f);
-
- fclose(f);
-
- remove("lzmacodec_temp.lzma");
-
- if (prop0 >= (9*5*5))
- {
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
- return PEC2_CODEC_ERROR_UNSPECIFIED;
- }
-
- for (pb = 0; prop0 >= (9 * 5); pb++, prop0 -= (9 * 5)) ;
-
- for (lp = 0; prop0 >= 9; lp++, prop0 -= 9) ;
-
- lc = prop0;
-
- lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * 4;
-
- /* header format:
- *
- * DWORD lzmaInternalSize
- * DWORD orgSize
- * DWORD cmpSize
- * BYTE pb
- * BYTE lp
- * BYTE lc
- * <compressed lzma data>
- */
-
- ((DWORD *)lpvDest)[0] = lzmaInternalSize;
- ((DWORD *)lpvDest)[1] = dwSize;
- ((DWORD *)lpvDest)[2] = dwDestSize;
-
- ((BYTE *)lpvDest)[12] = pb;
- ((BYTE *)lpvDest)[13] = lp;
- ((BYTE *)lpvDest)[14] = lc;
-
- dwDestSize += 15;
- }
-
- /* call callback to indicate result of encoding */
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ENCODE, dwSize, dwDestSize, dwSize);
-
- /* call callback to indicate compression is done */
- if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_DONE, dwSize, dwDestSize, 0);
-
- return dwDestSize;
- }
-
- DWORD WINAPI GetMaximumEncodedSize(DWORD dwSize)
- {
- return dwSize + dwSize/8 + 64;
- }
-
- DWORD WINAPI GetMaximumEncodingLevel(void)
- {
- return 0;
- }
-
- DWORD WINAPI GetCodecAuthor(WCHAR *pwszAuthorName, DWORD dwBufSize)
- {
- static const WCHAR wszString[] = L"J\x00f8rgen Ibsen (www.ibsensoftware.com)";
- unsigned int i;
-
- if (pwszAuthorName == NULL) return sizeof(wszString);
-
- for (i = 0; i < sizeof(wszString) / sizeof(wszString[0]); ++i)
- {
- pwszAuthorName[i] = wszString[i];
- }
-
- return sizeof(wszString) - sizeof(wszString[0]);
- }
-
- DWORD WINAPI GetCodecName(WCHAR *pwszCodecName, DWORD dwBufSize)
- {
- static const WCHAR wszString[] = L"LZMA SDK Codec (www.7-zip.org)";
- unsigned int i;
-
- if (pwszCodecName == NULL) return sizeof(wszString);
-
- for (i = 0; i < sizeof(wszString) / sizeof(wszString[0]); ++i)
- {
- pwszCodecName[i] = wszString[i];
- }
-
- return sizeof(wszString) - sizeof(wszString[0]);
- }
-
- DWORD WINAPI GetCodecVersion(DWORD *pdwSDKVersion)
- {
- if (pdwSDKVersion) *pdwSDKVersion = PEC2_CODEC_SDK_VERSION;
-
- return PEC2_LZMA_CODEC_VERSION;
- }
-
- DWORD WINAPI GetNumberOfCodecs()
- {
- return 1;
- }
-
- FARPROC WINAPI CodecGetProcAddress(DWORD dwCodecIndex, LPCSTR pszApi)
- {
- if (dwCodecIndex > 0) return NULL;
-
- if (!stricmp(pszApi, "DecodeSmall")) return &DecodeSmall;
- if (!stricmp(pszApi, "DecodeFast")) return &DecodeFast;
- if (!stricmp(pszApi, "GetDecodeSmallFuncSize")) return &GetDecodeSmallFuncSize;
- if (!stricmp(pszApi, "GetDecodeFastFuncSize")) return &GetDecodeFastFuncSize;
- if (!stricmp(pszApi, "Encode")) return &Encode;
- if (!stricmp(pszApi, "GetMaximumEncodedSize")) return &GetMaximumEncodedSize;
- if (!stricmp(pszApi, "GetMaximumEncodingLevel")) return &GetMaximumEncodingLevel;
- if (!stricmp(pszApi, "GetCodecAuthor")) return &GetCodecAuthor;
- if (!stricmp(pszApi, "GetCodecName")) return &GetCodecName;
- if (!stricmp(pszApi, "GetCodecVersion")) return &GetCodecVersion;
-
- return NULL;
- }
-
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
- {
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- break;
- case DLL_PROCESS_DETACH:
- break;
- }
-
- return TRUE;
- }
-