home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 October / CMCD1004.ISO / Software / Shareware / Utilitare / pec / pec2setup.exe / lzma / pec2codec / codec.c next >
Encoding:
C/C++ Source or Header  |  2004-05-09  |  7.1 KB  |  252 lines

  1. /*
  2.  * PECompact v2 LZMA CODEC
  3.  * Copyright (C) 2004 Joergen Ibsen (www.ibsensoftware.com)
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  */
  19.  
  20. #define WIN32_LEAN_AND_MEAN
  21.  
  22. #include <windows.h>
  23. #include <stdio.h>
  24.  
  25. #include "codec.h"
  26. #include "decode.h"
  27. #include "decodef.h"
  28.  
  29. #define LZMA_BASE_SIZE 1846
  30. #define LZMA_LIT_SIZE 768
  31.  
  32. BOOL execute(const char *cmdline)
  33. {
  34.     PROCESS_INFORMATION pinfo;
  35.     STARTUPINFO sinfo = { sizeof(STARTUPINFO) };
  36.     HANDLE hReadPipe, hWritePipe;
  37.     BOOL bRet;
  38.  
  39.     GetStartupInfo(&sinfo);
  40.  
  41.     sinfo.dwFlags     = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES;
  42.     sinfo.wShowWindow = SW_HIDE;
  43.  
  44.     bRet = CreateProcess(NULL, (char *)cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
  45.                          &sinfo, &pinfo);
  46.  
  47.     if (!bRet) return FALSE;
  48.  
  49.     /* wait for process to terminate */
  50.     WaitForSingleObject(pinfo.hProcess, INFINITE);
  51.  
  52.     /* close process handles to allow it to terminate */
  53.     CloseHandle(pinfo.hProcess);
  54.     CloseHandle(pinfo.hThread);
  55.  
  56.     return TRUE;
  57. }
  58.  
  59. DWORD WINAPI Encode(LPVOID lpvSource, DWORD dwSize, LPVOID lpvDest,
  60.                     DWORD *pdwDestSize, DWORD dwLevel, PFNCodecCallback pCodecCallback)
  61. {
  62.     DWORD dwDestSize;
  63.     void *lpvWorkmem;
  64.  
  65.     if (pdwDestSize == NULL)
  66.     {
  67.         if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
  68.         return PEC2_CODEC_ERROR_UNSPECIFIED;
  69.     }
  70.  
  71.     /* check destination buffer is large enough */
  72.     if (*pdwDestSize < (dwSize + dwSize/8 + 64))
  73.     {
  74.         *pdwDestSize = (dwSize + dwSize/8 + 64);
  75.         if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
  76.         return PEC2_CODEC_ERROR_INSUFFICIENT_BUFFER;
  77.     }
  78.  
  79.     /* call callback to indicate start of encoding */
  80.     if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ENCODE, 0, 0, dwSize);
  81.  
  82.     /* perform compression */
  83.     {
  84.         int lc, lp, pb;
  85.         unsigned int lzmaInternalSize;
  86.         unsigned char prop0;
  87.         FILE *f;
  88.  
  89.         f = fopen("lzmacodec_temp.dat", "wb");
  90.  
  91.         if (f == NULL) return PEC2_CODEC_ERROR_UNSPECIFIED;
  92.  
  93.         fwrite(lpvSource, dwSize, 1, f);
  94.  
  95.         fclose(f);
  96.  
  97.         execute("lzma.exe e lzmacodec_temp.dat lzmacodec_temp.lzma -fb255 -lc4 -d24");
  98.  
  99.         remove("lzmacodec_temp.dat");
  100.  
  101.         fopen("lzmacodec_temp.lzma", "rb");
  102.  
  103.         if (f == NULL) return PEC2_CODEC_ERROR_UNSPECIFIED;
  104.  
  105.         fseek(f, 0, SEEK_END);
  106.         dwDestSize = ftell(f);
  107.         fseek(f, 0, SEEK_SET);
  108.  
  109.         fread(&prop0, 1, 1, f);
  110.  
  111.         fseek(f, 13, SEEK_SET);
  112.  
  113.         dwDestSize -= 13;
  114.  
  115.         fread((unsigned char *)lpvDest + 15, dwDestSize, 1, f);
  116.  
  117.         fclose(f);
  118.  
  119.         remove("lzmacodec_temp.lzma");
  120.  
  121.         if (prop0 >= (9*5*5))
  122.         {
  123.             if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ERROR, PEC2_CODEC_ERROR_UNSPECIFIED, 0, 0);
  124.             return PEC2_CODEC_ERROR_UNSPECIFIED;
  125.         }
  126.  
  127.         for (pb = 0; prop0 >= (9 * 5); pb++, prop0 -= (9 * 5)) ;
  128.  
  129.         for (lp = 0; prop0 >= 9; lp++, prop0 -= 9) ;
  130.  
  131.         lc = prop0;
  132.  
  133.         lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * 4;
  134.  
  135.         /* header format:
  136.          *
  137.          *   DWORD  lzmaInternalSize
  138.          *   DWORD  orgSize
  139.          *   DWORD  cmpSize
  140.          *   BYTE   pb
  141.          *   BYTE   lp
  142.          *   BYTE   lc
  143.          *   <compressed lzma data>
  144.          */
  145.  
  146.         ((DWORD *)lpvDest)[0] = lzmaInternalSize;
  147.         ((DWORD *)lpvDest)[1] = dwSize;
  148.         ((DWORD *)lpvDest)[2] = dwDestSize;
  149.  
  150.         ((BYTE *)lpvDest)[12] = pb;
  151.         ((BYTE *)lpvDest)[13] = lp;
  152.         ((BYTE *)lpvDest)[14] = lc;
  153.  
  154.         dwDestSize += 15;
  155.     }
  156.  
  157.     /* call callback to indicate result of encoding */
  158.     if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_ENCODE, dwSize, dwDestSize, dwSize);
  159.  
  160.     /* call callback to indicate compression is done */
  161.     if (pCodecCallback) (*pCodecCallback)(PEC2_CODEC_ACTION_DONE, dwSize, dwDestSize, 0);
  162.  
  163.     return dwDestSize;
  164. }
  165.  
  166. DWORD WINAPI GetMaximumEncodedSize(DWORD dwSize)
  167. {
  168.     return dwSize + dwSize/8 + 64;
  169. }
  170.  
  171. DWORD WINAPI GetMaximumEncodingLevel(void)
  172. {
  173.     return 0;
  174. }
  175.  
  176. DWORD WINAPI GetCodecAuthor(WCHAR *pwszAuthorName, DWORD dwBufSize)
  177. {
  178.     static const WCHAR wszString[] = L"J\x00f8rgen Ibsen (www.ibsensoftware.com)";
  179.     unsigned int i;
  180.  
  181.     if (pwszAuthorName == NULL) return sizeof(wszString);
  182.  
  183.     for (i = 0; i < sizeof(wszString) / sizeof(wszString[0]); ++i)
  184.     {
  185.         pwszAuthorName[i] = wszString[i];
  186.     }
  187.  
  188.     return sizeof(wszString) - sizeof(wszString[0]);
  189. }
  190.  
  191. DWORD WINAPI GetCodecName(WCHAR *pwszCodecName, DWORD dwBufSize)
  192. {
  193.     static const WCHAR wszString[] = L"LZMA SDK Codec (www.7-zip.org)";
  194.     unsigned int i;
  195.  
  196.     if (pwszCodecName == NULL) return sizeof(wszString);
  197.  
  198.     for (i = 0; i < sizeof(wszString) / sizeof(wszString[0]); ++i)
  199.     {
  200.         pwszCodecName[i] = wszString[i];
  201.     }
  202.  
  203.     return sizeof(wszString) - sizeof(wszString[0]);
  204. }
  205.  
  206. DWORD WINAPI GetCodecVersion(DWORD *pdwSDKVersion)
  207. {
  208.     if (pdwSDKVersion) *pdwSDKVersion = PEC2_CODEC_SDK_VERSION;
  209.  
  210.     return PEC2_LZMA_CODEC_VERSION;
  211. }
  212.  
  213. DWORD WINAPI GetNumberOfCodecs()
  214. {
  215.     return 1;
  216. }
  217.  
  218. FARPROC WINAPI CodecGetProcAddress(DWORD dwCodecIndex, LPCSTR pszApi)
  219. {
  220.     if (dwCodecIndex > 0) return NULL;
  221.  
  222.     if (!stricmp(pszApi, "DecodeSmall")) return &DecodeSmall;
  223.     if (!stricmp(pszApi, "DecodeFast")) return &DecodeFast;
  224.     if (!stricmp(pszApi, "GetDecodeSmallFuncSize")) return &GetDecodeSmallFuncSize;
  225.     if (!stricmp(pszApi, "GetDecodeFastFuncSize")) return &GetDecodeFastFuncSize;
  226.     if (!stricmp(pszApi, "Encode")) return &Encode;
  227.     if (!stricmp(pszApi, "GetMaximumEncodedSize")) return &GetMaximumEncodedSize;
  228.     if (!stricmp(pszApi, "GetMaximumEncodingLevel")) return &GetMaximumEncodingLevel;
  229.     if (!stricmp(pszApi, "GetCodecAuthor")) return &GetCodecAuthor;
  230.     if (!stricmp(pszApi, "GetCodecName")) return &GetCodecName;
  231.     if (!stricmp(pszApi, "GetCodecVersion")) return &GetCodecVersion;
  232.  
  233.     return NULL;
  234. }
  235.  
  236. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
  237. {
  238.     switch (fdwReason)
  239.     {
  240.     case DLL_PROCESS_ATTACH:
  241.         break;
  242.     case DLL_THREAD_ATTACH:
  243.         break;
  244.     case DLL_THREAD_DETACH:
  245.         break;
  246.     case DLL_PROCESS_DETACH:
  247.         break;
  248.     }
  249.  
  250.     return TRUE;
  251. }
  252.