Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA_Alone/LzmaAlone.cpp, revision 1.1.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>