Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA_Alone/LzmaAlone.cpp, revision 1.1
1.1 ! misho 1: // LzmaAlone.cpp
! 2:
! 3: #include "StdAfx.h"
! 4:
! 5: #include "../../../Common/MyWindows.h"
! 6: #include "../../../Common/MyInitGuid.h"
! 7:
! 8: #include <stdio.h>
! 9:
! 10: #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
! 11: #include <fcntl.h>
! 12: #include <io.h>
! 13: #define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
! 14: #else
! 15: #define MY_SET_BINARY_MODE(file)
! 16: #endif
! 17:
! 18: #include "../../../Common/CommandLineParser.h"
! 19: #include "../../../Common/StringConvert.h"
! 20: #include "../../../Common/StringToInt.h"
! 21:
! 22: // #include "Windows/PropVariant.h"
! 23:
! 24: #include "../../Common/FileStreams.h"
! 25:
! 26: #include "../LZMA/LZMADecoder.h"
! 27: #include "../LZMA/LZMAEncoder.h"
! 28:
! 29: #include "LzmaBench.h"
! 30: #include "LzmaRam.h"
! 31:
! 32: extern "C"
! 33: {
! 34: #include "LzmaRamDecode.h"
! 35: }
! 36:
! 37: using namespace NCommandLineParser;
! 38:
! 39: namespace NKey {
! 40: enum Enum
! 41: {
! 42: kHelp1 = 0,
! 43: kHelp2,
! 44: kMode,
! 45: kDictionary,
! 46: kFastBytes,
! 47: kLitContext,
! 48: kLitPos,
! 49: kPosBits,
! 50: kMatchFinder,
! 51: kEOS,
! 52: kStdIn,
! 53: kStdOut,
! 54: kFilter86
! 55: };
! 56: }
! 57:
! 58: static const CSwitchForm kSwitchForms[] =
! 59: {
! 60: { L"?", NSwitchType::kSimple, false },
! 61: { L"H", NSwitchType::kSimple, false },
! 62: { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
! 63: { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
! 64: { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
! 65: { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
! 66: { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
! 67: { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
! 68: { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
! 69: { L"EOS", NSwitchType::kSimple, false },
! 70: { L"SI", NSwitchType::kSimple, false },
! 71: { L"SO", NSwitchType::kSimple, false },
! 72: { L"F86", NSwitchType::kSimple, false }
! 73: };
! 74:
! 75: static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
! 76:
! 77: static void PrintHelp()
! 78: {
! 79: fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
! 80: " e: encode file\n"
! 81: " d: decode file\n"
! 82: " b: Benchmark\n"
! 83: "<Switches>\n"
! 84: " -a{N}: set compression mode - [0, 2], default: 2 (max)\n"
! 85: " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n"
! 86: " -fb{N}: set number of fast bytes - [5, 255], default: 128\n"
! 87: " -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
! 88: " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
! 89: " -pb{N}: set number of pos bits - [0, 4], default: 2\n"
! 90: " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,\n"
! 91: " pat2h, pat3h, pat4h, hc3, hc4], default: bt4\n"
! 92: " -eos: write End Of Stream marker\n"
! 93: " -si: Read data from stdin\n"
! 94: " -so: Write data to stdout\n"
! 95: );
! 96: }
! 97:
! 98: static void PrintHelpAndExit(const char *s)
! 99: {
! 100: fprintf(stderr, "\nError: %s\n\n", s);
! 101: PrintHelp();
! 102: throw -1;
! 103: }
! 104:
! 105: static void IncorrectCommand()
! 106: {
! 107: PrintHelpAndExit("Incorrect command");
! 108: }
! 109:
! 110: static void WriteArgumentsToStringList(int numArguments, const char *arguments[],
! 111: UStringVector &strings)
! 112: {
! 113: for(int i = 1; i < numArguments; i++)
! 114: strings.Add(MultiByteToUnicodeString(arguments[i]));
! 115: }
! 116:
! 117: static bool GetNumber(const wchar_t *s, UInt32 &value)
! 118: {
! 119: value = 0;
! 120: if (MyStringLen(s) == 0)
! 121: return false;
! 122: const wchar_t *end;
! 123: UInt64 res = ConvertStringToUInt64(s, &end);
! 124: if (*end != L'\0')
! 125: return false;
! 126: if (res > 0xFFFFFFFF)
! 127: return false;
! 128: value = UInt32(res);
! 129: return true;
! 130: }
! 131:
! 132: int main2(int n, const char *args[])
! 133: {
! 134: fprintf(stderr, "\nLZMA 4.17 Copyright (c) 1999-2004 Igor Pavlov 2005-04-18\n");
! 135:
! 136: if (n == 1)
! 137: {
! 138: PrintHelp();
! 139: return 0;
! 140: }
! 141:
! 142: if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4)
! 143: {
! 144: fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
! 145: return 1;
! 146: }
! 147:
! 148: UStringVector commandStrings;
! 149: WriteArgumentsToStringList(n, args, commandStrings);
! 150: CParser parser(kNumSwitches);
! 151: try
! 152: {
! 153: parser.ParseStrings(kSwitchForms, commandStrings);
! 154: }
! 155: catch(...)
! 156: {
! 157: IncorrectCommand();
! 158: }
! 159:
! 160: if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
! 161: {
! 162: PrintHelp();
! 163: return 0;
! 164: }
! 165: const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
! 166:
! 167: int paramIndex = 0;
! 168: if (paramIndex >= nonSwitchStrings.Size())
! 169: IncorrectCommand();
! 170: const UString &command = nonSwitchStrings[paramIndex++];
! 171:
! 172: bool dictionaryIsDefined = false;
! 173: UInt32 dictionary = 1 << 21;
! 174: if(parser[NKey::kDictionary].ThereIs)
! 175: {
! 176: UInt32 dicLog;
! 177: if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
! 178: IncorrectCommand();
! 179: dictionary = 1 << dicLog;
! 180: dictionaryIsDefined = true;
! 181: }
! 182: UString mf = L"BT4";
! 183: if (parser[NKey::kMatchFinder].ThereIs)
! 184: mf = parser[NKey::kMatchFinder].PostStrings[0];
! 185:
! 186: if (command.CompareNoCase(L"b") == 0)
! 187: {
! 188: const UInt32 kNumDefaultItereations = 10;
! 189: UInt32 numIterations = kNumDefaultItereations;
! 190: {
! 191: if (paramIndex < nonSwitchStrings.Size())
! 192: if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
! 193: numIterations = kNumDefaultItereations;
! 194: }
! 195: return LzmaBenchmark(stderr, numIterations, dictionary,
! 196: mf.CompareNoCase(L"BT4") == 0);
! 197: }
! 198:
! 199: bool encodeMode = false;
! 200: if (command.CompareNoCase(L"e") == 0)
! 201: encodeMode = true;
! 202: else if (command.CompareNoCase(L"d") == 0)
! 203: encodeMode = false;
! 204: else
! 205: IncorrectCommand();
! 206:
! 207: bool stdInMode = parser[NKey::kStdIn].ThereIs;
! 208: bool stdOutMode = parser[NKey::kStdOut].ThereIs;
! 209:
! 210: CMyComPtr<ISequentialInStream> inStream;
! 211: CInFileStream *inStreamSpec = 0;
! 212: if (stdInMode)
! 213: {
! 214: inStream = new CStdInFileStream;
! 215: MY_SET_BINARY_MODE(stdin);
! 216: }
! 217: else
! 218: {
! 219: if (paramIndex >= nonSwitchStrings.Size())
! 220: IncorrectCommand();
! 221: const UString &inputName = nonSwitchStrings[paramIndex++];
! 222: inStreamSpec = new CInFileStream;
! 223: inStream = inStreamSpec;
! 224: if (!inStreamSpec->Open(GetSystemString(inputName)))
! 225: {
! 226: fprintf(stderr, "\nError: can not open input file %s\n",
! 227: (const char *)GetOemString(inputName));
! 228: return 1;
! 229: }
! 230: }
! 231:
! 232: CMyComPtr<ISequentialOutStream> outStream;
! 233: if (stdOutMode)
! 234: {
! 235: outStream = new CStdOutFileStream;
! 236: MY_SET_BINARY_MODE(stdout);
! 237: }
! 238: else
! 239: {
! 240: if (paramIndex >= nonSwitchStrings.Size())
! 241: IncorrectCommand();
! 242: const UString &outputName = nonSwitchStrings[paramIndex++];
! 243: COutFileStream *outStreamSpec = new COutFileStream;
! 244: outStream = outStreamSpec;
! 245: if (!outStreamSpec->Create(GetSystemString(outputName), true))
! 246: {
! 247: fprintf(stderr, "\nError: can not open output file %s\n",
! 248: (const char *)GetOemString(outputName));
! 249: return 1;
! 250: }
! 251: }
! 252:
! 253: if (parser[NKey::kFilter86].ThereIs)
! 254: {
! 255: // -f86 switch is for x86 filtered mode: BCJ + LZMA.
! 256: if (parser[NKey::kEOS].ThereIs || stdInMode)
! 257: throw "Can not use stdin in this mode";
! 258: UInt64 fileSize;
! 259: inStreamSpec->File.GetLength(fileSize);
! 260: if (fileSize > 0xF0000000)
! 261: throw "File is too big";
! 262: UInt32 inSize = (UInt32)fileSize;
! 263: Byte *inBuffer = (Byte *)MyAlloc((size_t)inSize);
! 264: if (inBuffer == 0)
! 265: throw "Can not allocate memory";
! 266:
! 267: UInt32 processedSize;
! 268: if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK)
! 269: throw "Can not read";
! 270: if ((UInt32)inSize != processedSize)
! 271: throw "Read size error";
! 272:
! 273: Byte *outBuffer;
! 274: size_t outSizeProcessed;
! 275: if (encodeMode)
! 276: {
! 277: // we allocate 105% of original size for output buffer
! 278: size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
! 279: outBuffer = (Byte *)MyAlloc((size_t)outSize);
! 280: if (outBuffer == 0)
! 281: throw "Can not allocate memory";
! 282: if (!dictionaryIsDefined)
! 283: dictionary = 1 << 23;
! 284: int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed,
! 285: dictionary, SZ_FILTER_AUTO);
! 286: if (res != 0)
! 287: {
! 288: fprintf(stderr, "\nEncoder error = %d\n", (int)res);
! 289: return 1;
! 290: }
! 291: }
! 292: else
! 293: {
! 294: size_t outSize;
! 295: if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
! 296: throw "data error";
! 297: outBuffer = (Byte *)MyAlloc(outSize);
! 298: if (outBuffer == 0)
! 299: throw "Can not allocate memory";
! 300:
! 301: int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
! 302: if (res != 0)
! 303: throw "LzmaDecoder error";
! 304: }
! 305: if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
! 306: throw "Can not write";
! 307: MyFree(outBuffer);
! 308: MyFree(inBuffer);
! 309: return 0;
! 310: }
! 311:
! 312:
! 313: UInt64 fileSize;
! 314: if (encodeMode)
! 315: {
! 316: NCompress::NLZMA::CEncoder *encoderSpec =
! 317: new NCompress::NLZMA::CEncoder;
! 318: CMyComPtr<ICompressCoder> encoder = encoderSpec;
! 319:
! 320: if (!dictionaryIsDefined)
! 321: dictionary = 1 << 23;
! 322:
! 323: UInt32 posStateBits = 2;
! 324: UInt32 litContextBits = 3; // for normal files
! 325: // UInt32 litContextBits = 0; // for 32-bit data
! 326: UInt32 litPosBits = 0;
! 327: // UInt32 litPosBits = 2; // for 32-bit data
! 328: UInt32 algorithm = 2;
! 329: UInt32 numFastBytes = 128;
! 330:
! 331: bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
! 332:
! 333: if(parser[NKey::kMode].ThereIs)
! 334: if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
! 335: IncorrectCommand();
! 336:
! 337: if(parser[NKey::kFastBytes].ThereIs)
! 338: if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
! 339: IncorrectCommand();
! 340: if(parser[NKey::kLitContext].ThereIs)
! 341: if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
! 342: IncorrectCommand();
! 343: if(parser[NKey::kLitPos].ThereIs)
! 344: if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
! 345: IncorrectCommand();
! 346: if(parser[NKey::kPosBits].ThereIs)
! 347: if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
! 348: IncorrectCommand();
! 349:
! 350: PROPID propIDs[] =
! 351: {
! 352: NCoderPropID::kDictionarySize,
! 353: NCoderPropID::kPosStateBits,
! 354: NCoderPropID::kLitContextBits,
! 355: NCoderPropID::kLitPosBits,
! 356: NCoderPropID::kAlgorithm,
! 357: NCoderPropID::kNumFastBytes,
! 358: NCoderPropID::kMatchFinder,
! 359: NCoderPropID::kEndMarker
! 360: };
! 361: const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
! 362: /*
! 363: NWindows::NCOM::CPropVariant properties[kNumProps];
! 364: properties[0] = UInt32(dictionary);
! 365: properties[1] = UInt32(posStateBits);
! 366: properties[2] = UInt32(litContextBits);
! 367:
! 368: properties[3] = UInt32(litPosBits);
! 369: properties[4] = UInt32(algorithm);
! 370: properties[5] = UInt32(numFastBytes);
! 371: properties[6] = mf;
! 372: properties[7] = eos;
! 373: */
! 374: PROPVARIANT properties[kNumProps];
! 375: for (int p = 0; p < 6; p++)
! 376: properties[p].vt = VT_UI4;
! 377: properties[0].ulVal = UInt32(dictionary);
! 378: properties[1].ulVal = UInt32(posStateBits);
! 379: properties[2].ulVal = UInt32(litContextBits);
! 380: properties[3].ulVal = UInt32(litPosBits);
! 381: properties[4].ulVal = UInt32(algorithm);
! 382: properties[5].ulVal = UInt32(numFastBytes);
! 383:
! 384: properties[6].vt = VT_BSTR;
! 385: properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
! 386:
! 387: properties[7].vt = VT_BOOL;
! 388: properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
! 389:
! 390: if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
! 391: IncorrectCommand();
! 392: encoderSpec->WriteCoderProperties(outStream);
! 393:
! 394: if (eos || stdInMode)
! 395: fileSize = (UInt64)(Int64)-1;
! 396: else
! 397: inStreamSpec->File.GetLength(fileSize);
! 398:
! 399: for (int i = 0; i < 8; i++)
! 400: {
! 401: Byte b = Byte(fileSize >> (8 * i));
! 402: if (outStream->Write(&b, sizeof(b), 0) != S_OK)
! 403: {
! 404: fprintf(stderr, "Write error");
! 405: return 1;
! 406: }
! 407: }
! 408: HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
! 409: if (result == E_OUTOFMEMORY)
! 410: {
! 411: fprintf(stderr, "\nError: Can not allocate memory\n");
! 412: return 1;
! 413: }
! 414: else if (result != S_OK)
! 415: {
! 416: fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
! 417: return 1;
! 418: }
! 419: }
! 420: else
! 421: {
! 422: NCompress::NLZMA::CDecoder *decoderSpec =
! 423: new NCompress::NLZMA::CDecoder;
! 424: CMyComPtr<ICompressCoder> decoder = decoderSpec;
! 425: const UInt32 kPropertiesSize = 5;
! 426: Byte properties[kPropertiesSize];
! 427: UInt32 processedSize;
! 428: if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK)
! 429: {
! 430: fprintf(stderr, "Read error");
! 431: return 1;
! 432: }
! 433: if (processedSize != kPropertiesSize)
! 434: {
! 435: fprintf(stderr, "Read error");
! 436: return 1;
! 437: }
! 438: if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
! 439: {
! 440: fprintf(stderr, "SetDecoderProperties error");
! 441: return 1;
! 442: }
! 443: fileSize = 0;
! 444: for (int i = 0; i < 8; i++)
! 445: {
! 446: Byte b;
! 447: if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK)
! 448: {
! 449: fprintf(stderr, "Read error");
! 450: return 1;
! 451: }
! 452: if (processedSize != 1)
! 453: {
! 454: fprintf(stderr, "Read error");
! 455: return 1;
! 456: }
! 457: fileSize |= ((UInt64)b) << (8 * i);
! 458: }
! 459: if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
! 460: {
! 461: fprintf(stderr, "Decoder error");
! 462: return 1;
! 463: }
! 464: }
! 465: return 0;
! 466: }
! 467:
! 468: int main(int n, const char *args[])
! 469: {
! 470: try { return main2(n, args); }
! 471: catch(const char *s)
! 472: {
! 473: fprintf(stderr, "\nError: %s\n", s);
! 474: return 1;
! 475: }
! 476: catch(...)
! 477: {
! 478: fprintf(stderr, "\nError\n");
! 479: return 1;
! 480: }
! 481: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>