misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateTest.c
changeset 13904 99b265e0d1d0
parent 13903 5f819b90d479
child 13905 b172a5d40eee
equal deleted inserted replaced
13903:5f819b90d479 13904:99b265e0d1d0
     1 /* 
       
     2 LzmaStateTest.c
       
     3 Test application for LZMA Decoder (State version)
       
     4 
       
     5 This file written and distributed to public domain by Igor Pavlov.
       
     6 This file is part of LZMA SDK 4.26 (2005-08-02)
       
     7 */
       
     8 
       
     9 #include <stdio.h>
       
    10 #include <stdlib.h>
       
    11 #include <string.h>
       
    12 
       
    13 #include "LzmaStateDecode.h"
       
    14 
       
    15 const char *kCantReadMessage = "Can not read input file";
       
    16 const char *kCantWriteMessage = "Can not write output file";
       
    17 const char *kCantAllocateMessage = "Can not allocate memory";
       
    18 
       
    19 #define kInBufferSize (1 << 15)
       
    20 #define kOutBufferSize (1 << 15)
       
    21 
       
    22 unsigned char g_InBuffer[kInBufferSize];
       
    23 unsigned char g_OutBuffer[kOutBufferSize];
       
    24 
       
    25 size_t MyReadFile(FILE *file, void *data, size_t size)
       
    26   { return fread(data, 1, size, file); }
       
    27 
       
    28 int MyReadFileAndCheck(FILE *file, void *data, size_t size)
       
    29   { return (MyReadFile(file, data, size) == size); }
       
    30 
       
    31 int PrintError(char *buffer, const char *message)
       
    32 {
       
    33   sprintf(buffer + strlen(buffer), "\nError: ");
       
    34   sprintf(buffer + strlen(buffer), message);
       
    35   return 1;
       
    36 }
       
    37 
       
    38 int main3(FILE *inFile, FILE *outFile, char *rs)
       
    39 {
       
    40   /* We use two 32-bit integers to construct 64-bit integer for file size.
       
    41      You can remove outSizeHigh, if you don't need >= 4GB supporting,
       
    42      or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
       
    43   UInt32 outSize = 0;
       
    44   UInt32 outSizeHigh = 0; 
       
    45   
       
    46   int waitEOS = 1; 
       
    47   /* waitEOS = 1, if there is no uncompressed size in headers, 
       
    48    so decoder will wait EOS (End of Stream Marker) in compressed stream */
       
    49 
       
    50   int i;
       
    51   int res = 0;
       
    52   CLzmaDecoderState state;  /* it's about 140 bytes structure, if int is 32-bit */
       
    53   unsigned char properties[LZMA_PROPERTIES_SIZE];
       
    54   SizeT inAvail = 0;
       
    55   unsigned char *inBuffer = 0;
       
    56 
       
    57   if (sizeof(UInt32) < 4)
       
    58     return PrintError(rs, "LZMA decoder needs correct UInt32");
       
    59 
       
    60   /* Read LZMA properties for compressed stream */
       
    61 
       
    62   if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
       
    63     return PrintError(rs, kCantReadMessage);
       
    64 
       
    65   /* Read uncompressed size */
       
    66   
       
    67   for (i = 0; i < 8; i++)
       
    68   {
       
    69     unsigned char b;
       
    70     if (!MyReadFileAndCheck(inFile, &b, 1))
       
    71       return PrintError(rs, kCantReadMessage);
       
    72     if (b != 0xFF)
       
    73       waitEOS = 0;
       
    74     if (i < 4)
       
    75       outSize += (UInt32)(b) << (i * 8);
       
    76     else
       
    77       outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
       
    78   }
       
    79 
       
    80   /* Decode LZMA properties and allocate memory */
       
    81   
       
    82   if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
       
    83     return PrintError(rs, "Incorrect stream properties");
       
    84   state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
       
    85   if (state.Probs == 0)
       
    86     return PrintError(rs, kCantAllocateMessage);
       
    87   
       
    88   if (state.Properties.DictionarySize == 0)
       
    89     state.Dictionary = 0;
       
    90   else
       
    91   {
       
    92     state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
       
    93     if (state.Dictionary == 0)
       
    94     {
       
    95       free(state.Probs);
       
    96       return PrintError(rs, kCantAllocateMessage);
       
    97     }
       
    98   }
       
    99   
       
   100   /* Decompress */
       
   101   
       
   102   LzmaDecoderInit(&state);
       
   103   
       
   104   do
       
   105   {
       
   106     SizeT inProcessed, outProcessed;
       
   107     int finishDecoding;
       
   108     UInt32 outAvail = kOutBufferSize;
       
   109     if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
       
   110       outAvail = outSize;
       
   111     if (inAvail == 0)
       
   112     {
       
   113       inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
       
   114       inBuffer = g_InBuffer;
       
   115     }
       
   116     finishDecoding = (inAvail == 0);
       
   117     res = LzmaDecode(&state,
       
   118         inBuffer, inAvail, &inProcessed,
       
   119         g_OutBuffer, outAvail, &outProcessed,
       
   120         finishDecoding);
       
   121     if (res != 0)
       
   122     {
       
   123       sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
       
   124       res = 1;
       
   125       break;
       
   126     }
       
   127     inAvail -= inProcessed;
       
   128     inBuffer += inProcessed;
       
   129     
       
   130     if (outFile != 0)  
       
   131       if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
       
   132       {
       
   133         PrintError(rs, kCantWriteMessage);
       
   134         res = 1;
       
   135         break;
       
   136       }
       
   137       
       
   138     if (outSize < outProcessed)
       
   139       outSizeHigh--;
       
   140     outSize -= (UInt32)outProcessed;
       
   141     outSize &= 0xFFFFFFFF;
       
   142 
       
   143     if (outProcessed == 0 && finishDecoding)
       
   144     {
       
   145       if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
       
   146         res = 1;
       
   147       break;
       
   148     }
       
   149   }
       
   150   while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0  || waitEOS);
       
   151 
       
   152   free(state.Dictionary);
       
   153   free(state.Probs);
       
   154   return res;
       
   155 }
       
   156 
       
   157 int main2(int numArgs, const char *args[], char *rs)
       
   158 {
       
   159   FILE *inFile = 0;
       
   160   FILE *outFile = 0;
       
   161   int res;
       
   162 
       
   163   sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov  2005-08-02\n");
       
   164   if (numArgs < 2 || numArgs > 3)
       
   165   {
       
   166     sprintf(rs + strlen(rs), "\nUsage:  lzmadec file.lzma [outFile]\n");
       
   167     return 1;
       
   168   }
       
   169 
       
   170   inFile = fopen(args[1], "rb");
       
   171   if (inFile == 0)
       
   172     return PrintError(rs, "Can not open input file");
       
   173 
       
   174   if (numArgs > 2)
       
   175   {
       
   176     outFile = fopen(args[2], "wb+");
       
   177     if (outFile == 0)
       
   178       return PrintError(rs, "Can not open output file");
       
   179   }
       
   180 
       
   181   res = main3(inFile, outFile, rs);
       
   182 
       
   183   if (outFile != 0)
       
   184     fclose(outFile);
       
   185   fclose(inFile);
       
   186   return res;
       
   187 }
       
   188 
       
   189 int main(int numArgs, const char *args[])
       
   190 {
       
   191   char rs[800] = { 0 };
       
   192   int res = main2(numArgs, args, rs);
       
   193   printf(rs);
       
   194   return res;
       
   195 }