• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                這份代碼跟上一次相比,修正了以下部分:

                1、可修改的Window Size。壓縮流會把Window Size寫進(jìn)去,解壓流能夠自動獲取。
                2、發(fā)現(xiàn)冗余的地方,每一個標(biāo)記的壓縮塊節(jié)省了一位。
                3、如果用戶一次性寫入的字節(jié)不夠多則會緩存起來,上一版本則是直接壓縮完。這樣會丟失某些原本可以壓縮的數(shù)據(jù),因此修正。

                這次修改主要用于縮小壓縮后的數(shù)據(jù)的尺寸。

                頭文件:
              1 /*******************************************************************************
              2 Vczh Library++ 2.0
              3 數(shù)據(jù)結(jié)構(gòu)::壓縮流
              4 開發(fā)者:陳梓瀚
              5 
              6 接口:
              7 類:
              8   VL_CompressedStream                    :壓縮流
              9   VL_LZ77Stream                            :LZ77壓縮流
             10   VL_LZWStream                            :LZW壓縮流
             11   VL_HuffmanStream                        :Canonical Huffman壓縮流
             12 函數(shù):
             13 *******************************************************************************/
             14 #ifndef VL_COMPRESSION
             15 #define VL_COMPRESSION
             16 
             17 #include "VL_Stream.h"
             18 #include "VL_DataAccess.h"
             19 
             20 namespace vl
             21 {
             22     namespace stream
             23     {
             24         using namespace collection;
             25 
             26 /*********************************************************************************************************
             27 壓縮流
             28 *********************************************************************************************************/
             29 
             30         class VL_CompressedStream : public VL_Base , public IVL_Stream
             31         {
             32         public:
             33             enum VLE_OpenMode
             34             {
             35                 vomRead,
             36                 vomWrite,
             37             };
             38 
             39             class Compressor : public IVL_Interface
             40             {
             41             public:
             42                 virtual void            SetStream(IVL_Stream* Stream)=0;
             43                 virtual VInt            Write(VPointer Data , VInt ByteCount)=0;
             44             };
             45 
             46             class Decompressor : public IVL_Interface
             47             {
             48             public:
             49                 virtual void            SetStream(IVL_Stream* Stream)=0;
             50                 virtual VInt            Read(VPointer Data , VInt ByteCount)=0;
             51             };
             52         protected:
             53             IVL_Stream*                    FStream;
             54             VBool                        FOwned;
             55             VLE_OpenMode                FMode;
             56             VSize                        FPosition;
             57             Compressor*                    FCompressor;
             58             Decompressor*                FDecompressor;
             59 
             60             VBuffer                        FPeekBuffer;
             61             VInt                        FPeekBufferSize;
             62             VInt                        FAvailablePeekSize;
             63 
             64             void                        Init(IVL_Stream* Stream , VBool Owned , Compressor* aCompressor);
             65             void                        Init(IVL_Stream* Stream , VBool Owned , Decompressor* aDecompressor);
             66 
             67             VL_CompressedStream();
             68         public:
             69             ~VL_CompressedStream();
             70 
             71             VBool                        CanRead();
             72             VBool                        CanPeek();
             73             VBool                        CanWrite();
             74             VBool                        CanClose();
             75             VBool                        CanSeek();
             76             VBool                        CanGrow();
             77             VInt                        Read(VPointer Data , VInt ByteCount);
             78             VInt                        Peek(VPointer Data , VInt ByteCount);
             79             VInt                        Write(VPointer Data , VInt ByteCount);
             80             void                        Close();
             81             VBool                        IsAvailable();
             82             VSize                        Position();
             83             VSize                        Size();
             84             VSize                        MaxWriteSize();
             85             void                        SeekFromBegin(VSize Offset);
             86             void                        SeekFromEnd(VSize Offset);
             87             void                        Seek(VSize Offset);
             88             VBool                        IsEnd();
             89         };
             90 
             91         class VL_LZ77Stream : public VL_CompressedStream
             92         {
             93         public:
             94             enum VLE_WindowMode
             95             {
             96                 vwm128=7,
             97                 vwm256,
             98                 vwm512,
             99                 vwm1024,
            100                 vwm2048,
            101                 vwmAuto=0,
            102                 vwmMin=vwm128,
            103                 vwmMax=vwm2048
            104 
            105             };
            106 
            107             VL_LZ77Stream(IVL_Stream* Stream , VLE_OpenMode OpenMode , VLE_WindowMode WindowMode=vwmAuto , VBool Owned=false);
            108         };
            109 
            110 /*********************************************************************************************************
            111 LZ77壓縮算法
            112 
            113 第一個字節(jié):window level, window size = 2 ^ window level
            114 壓縮塊描述:
            115 [0:wild][A:byte count-1][data]
            116 [1:encoded][A:byte count-1][B:index]
            117 A : 0 - (WindowSize-1)
            118 B : 0 - (WindowSize-1)
            119 *********************************************************************************************************/
            120 
            121         namespace LZ77Algorithms
            122         {
            123             class AlgorithmBase : public VL_Base
            124             {
            125             protected:
            126 
            127                 VInt                        WindowSize;
            128                 VInt                        MaxBlockSize;
            129                 VInt                        DoubleMaxBlockSize;
            130                 VInt                        ByteCountBitCount;
            131                 VInt                        ByteIndexBitCount;
            132 
            133                 VBuffer                        FWindow;                    /*滑動窗口,尺寸=WindowSize*3*/
            134                 VSize                        FPosition;                    /*當(dāng)前位置*/
            135                 VInt                        FUsedWindowSize;            /*窗口有效數(shù)據(jù)大小*/
            136                 VSize                        FWindowStartPosition;        /*窗口的起始位置*/
            137 
            138                 AlgorithmBase(VInt WindowSizeLevel);                    /*窗口尺寸為2的WindowSizeLevel次方*/
            139                 ~AlgorithmBase();
            140             };
            141 
            142             class Compressor : public AlgorithmBase , public VL_CompressedStream::Compressor
            143             {
            144             protected:
            145                 VL_BitWriter*                FBitWriter;
            146                 VInt                        FUsedFullWindowSize;        /*緩沖區(qū)有效數(shù)據(jù)大小*/
            147 
            148                 VInt                        CompressAndWrite(VInt ByteCount);
            149             public:
            150                 Compressor(VInt WindowSizeLevel);
            151                 ~Compressor();
            152 
            153                 void                        SetStream(IVL_Stream* Stream);
            154                 VInt                        Write(VPointer Data , VInt ByteCount);
            155             };
            156 
            157             class Decompressor : public AlgorithmBase , public VL_CompressedStream::Decompressor
            158             {
            159             protected:
            160                 VL_BitReader*                FReader;
            161 
            162                 VInt                        DecompressBlock();
            163             public:
            164                 Decompressor(VInt WindowSizeLevel);
            165                 ~Decompressor();
            166 
            167                 void                        SetStream(IVL_Stream* Stream);
            168                 VInt                        Read(VPointer Data , VInt ByteCount);
            169             };
            170 
            171         }
            172     }
            173 }
            174 
            175 #endif

                實現(xiàn)文件:
              1 #include "VL_Compression.h"
              2 
              3 namespace vl
              4 {
              5     namespace stream
              6     {
              7 
              8 /*********************************************************************************************************
              9 VL_CompressedStream
             10 *********************************************************************************************************/
             11 
             12         void VL_CompressedStream::Init(IVL_Stream* Stream , VBool Owned , Compressor* aCompressor)
             13         {
             14             FStream=Stream;
             15             FOwned=Owned;
             16             FMode=vomWrite;
             17             FCompressor=aCompressor;
             18             FCompressor->SetStream(FStream);
             19             FDecompressor=0;
             20         }
             21 
             22         void VL_CompressedStream::Init(IVL_Stream* Stream , VBool Owned , Decompressor* aDecompressor)
             23         {
             24             FStream=Stream;
             25             FOwned=Owned;
             26             FMode=vomRead;
             27             FCompressor=0;
             28             FDecompressor=aDecompressor;
             29             FDecompressor->SetStream(FStream);
             30         }
             31 
             32         VL_CompressedStream::VL_CompressedStream()
             33         {
             34             FStream=0;
             35             FOwned=false;
             36             FPosition=0;
             37 
             38             FPeekBuffer=0;
             39             FPeekBufferSize=0;
             40             FAvailablePeekSize=0;
             41         }
             42 
             43         VL_CompressedStream::~VL_CompressedStream()
             44         {
             45             Close();
             46         }
             47 
             48         VBool VL_CompressedStream::CanRead()
             49         {
             50             return IsAvailable() && (FMode==vomRead) && FStream->CanRead();
             51         }
             52 
             53         VBool VL_CompressedStream::CanPeek()
             54         {
             55             return IsAvailable() && (FMode==vomRead) && FStream->CanRead();
             56         }
             57 
             58         VBool VL_CompressedStream::CanWrite()
             59         {
             60             return IsAvailable() && (FMode==vomWrite) && FStream->CanWrite();
             61         }
             62 
             63         VBool VL_CompressedStream::CanClose()
             64         {
             65             return IsAvailable() && FStream->CanClose();
             66         }
             67 
             68         VBool VL_CompressedStream::CanSeek()
             69         {
             70             return false;
             71         }
             72 
             73         VBool VL_CompressedStream::CanGrow()
             74         {
             75             return CanWrite();
             76         }
             77 
             78         VInt VL_CompressedStream::Read(VPointer Data , VInt ByteCount)
             79         {
             80             if(CanRead())
             81             {
             82                 if(!FAvailablePeekSize)
             83                 {
             84                     ByteCount=FDecompressor->Read(Data,ByteCount);
             85                     FPosition+=ByteCount;
             86                     return ByteCount;
             87                 }
             88                 else if(FAvailablePeekSize>=ByteCount)
             89                 {
             90                     memcpy(Data,FPeekBuffer,ByteCount);
             91                     FAvailablePeekSize-=ByteCount;
             92                     memmove(FPeekBuffer,FPeekBuffer+ByteCount,FAvailablePeekSize);
             93                     FPosition+=ByteCount;
             94                     return ByteCount;
             95                 }
             96                 else
             97                 {
             98                     VBuffer DataBuffer=(VBuffer)Data;
             99                     memcpy(DataBuffer,FPeekBuffer,FAvailablePeekSize);
            100                     ByteCount=FAvailablePeekSize+FDecompressor->Read(DataBuffer+FAvailablePeekSize,ByteCount-FAvailablePeekSize);
            101                     FAvailablePeekSize=0;
            102                     FPosition+=ByteCount;
            103                     return ByteCount;
            104                 }
            105             }
            106             else
            107             {
            108                 return -1;
            109             }
            110         }
            111 
            112         VInt VL_CompressedStream::Peek(VPointer Data , VInt ByteCount)
            113         {
            114             if(CanPeek())
            115             {
            116                 VInt ExtendSize=ByteCount-FAvailablePeekSize;
            117                 if(ExtendSize>0)
            118                 {
            119                     if(FPeekBufferSize<ByteCount)
            120                     {
            121                         VBuffer NewPeekBuffer=new VByte[ByteCount];
            122                         if(FPeekBuffer)
            123                         {
            124                             memcpy(NewPeekBuffer,FPeekBuffer,FAvailablePeekSize);
            125                             delete[] FPeekBuffer;
            126                         }
            127                         FPeekBuffer=NewPeekBuffer;
            128                         FPeekBufferSize=ByteCount;
            129                     }
            130                     FAvailablePeekSize+=FDecompressor->Read(FPeekBuffer+FAvailablePeekSize,ExtendSize);
            131                 }
            132                 if(FAvailablePeekSize<ByteCount)
            133                 {
            134                     ByteCount=FAvailablePeekSize;
            135                 }
            136                 memcpy(Data,FPeekBuffer,ByteCount);
            137                 return ByteCount;
            138             }
            139             else
            140             {
            141                 return -1;
            142             }
            143         }
            144 
            145         VInt VL_CompressedStream::Write(VPointer Data , VInt ByteCount)
            146         {
            147             if(CanWrite())
            148             {
            149                 ByteCount=FCompressor->Write(Data,ByteCount);
            150                 FPosition+=ByteCount;
            151                 return ByteCount;
            152             }
            153             else
            154             {
            155                 return -1;
            156             }
            157         }
            158 
            159         void VL_CompressedStream::Close()
            160         {
            161             if(FCompressor)
            162             {
            163                 delete FCompressor;
            164                 FCompressor=0;
            165             }
            166             if(FDecompressor)
            167             {
            168                 delete FDecompressor;
            169                 FDecompressor=0;
            170             }
            171             if(FPeekBuffer)
            172             {
            173                 delete[] FPeekBuffer;
            174                 FPeekBuffer=0;
            175             }
            176             if(FStream)
            177             {
            178                 if(FOwned)
            179                 {
            180                     FStream->Close();
            181                     delete FStream;
            182                     FOwned=false;
            183                 }
            184                 FStream=0;
            185             }
            186         }
            187 
            188         VBool VL_CompressedStream::IsAvailable()
            189         {
            190             return FStream && FStream->IsAvailable();
            191         }
            192 
            193         VSize VL_CompressedStream::Position()
            194         {
            195             return IsAvailable()?FPosition:-1;
            196         }
            197 
            198         VSize VL_CompressedStream::Size()
            199         {
            200             return -1;
            201         }
            202 
            203         VSize VL_CompressedStream::MaxWriteSize()
            204         {
            205             return -1;
            206         }
            207 
            208         void VL_CompressedStream::SeekFromBegin(VSize Offset)
            209         {
            210         }
            211 
            212         void VL_CompressedStream::SeekFromEnd(VSize Offset)
            213         {
            214         }
            215 
            216         void VL_CompressedStream::Seek(VSize Offset)
            217         {
            218         }
            219 
            220         VBool VL_CompressedStream::IsEnd()
            221         {
            222             return IsAvailable()?FStream->IsEnd():true;
            223         }
            224 
            225 /*********************************************************************************************************
            226 VL_LZ77Stream
            227 *********************************************************************************************************/
            228 
            229         VL_LZ77Stream::VL_LZ77Stream(IVL_Stream* Stream , VLE_OpenMode OpenMode , VLE_WindowMode WindowMode , VBool Owned)
            230         {
            231             switch(OpenMode)
            232             {
            233             case vomRead:
            234                 if(WindowMode==vwmAuto)
            235                 {
            236                     VByte BitCount=0;
            237                     if(Stream->Read(&BitCount,sizeof(BitCount))==sizeof(BitCount))
            238                     {
            239                         if(BitCount>=vwmMin && BitCount<=vwmMax)
            240                         {
            241                             Init(Stream,Owned,new LZ77Algorithms::Decompressor(BitCount));
            242                         }
            243                     }
            244                 }
            245                 break;
            246             case vomWrite:
            247                 if(WindowMode==vwmAuto)
            248                 {
            249                     WindowMode=vwm1024;
            250                 }
            251                 if(WindowMode>=vwmMin && WindowMode<=vwmMax)
            252                 {
            253                     VByte BitCount=(VByte)WindowMode;
            254                     Stream->Write(&BitCount,sizeof(BitCount));
            255                     Init(Stream,Owned,new LZ77Algorithms::Compressor(WindowMode));
            256                 }
            257                 break;
            258             }
            259         }
            260 
            261 /*********************************************************************************************************
            262 LZ77Algorithms::AlgorithmBase
            263 *********************************************************************************************************/
            264 
            265         namespace LZ77Algorithms
            266         {
            267 
            268             AlgorithmBase::AlgorithmBase(VInt WindowSizeLevel)
            269             {
            270                 WindowSize=1<<WindowSizeLevel;
            271                 MaxBlockSize=WindowSize;
            272                 DoubleMaxBlockSize=MaxBlockSize*2;
            273                 ByteCountBitCount=WindowSizeLevel;
            274                 ByteIndexBitCount=WindowSizeLevel;
            275 
            276                 FWindow=new VByte[WindowSize*3];
            277                 FPosition=0;
            278                 FUsedWindowSize=0;
            279                 FWindowStartPosition=0;
            280             }
            281 
            282             AlgorithmBase::~AlgorithmBase()
            283             {
            284                 delete[] FWindow;
            285             }
            286 
            287 /*********************************************************************************************************
            288 LZ77Algorithms::Compressor
            289 *********************************************************************************************************/
            290 
            291             struct CompressionRecord
            292             {
            293                 VBool Compressed;
            294                 VInt Start;
            295                 VInt Size;
            296             };
            297 
            298             // 2 <= compressed size <= extended size
            299             CompressionRecord TestCompression(VBuffer Window , VInt WindowSize , VInt ExtendedSize)
            300             {
            301                 CompressionRecord Record;
            302                 Record.Compressed=false;
            303                 Record.Start=0;
            304                 Record.Size=1;
            305                 for(VInt i=0;i<WindowSize;i++)
            306                 {
            307                     VBuffer Read1=Window+i;
            308                     VBuffer Read2=Window+WindowSize;
            309                     VInt CurrentSize=0;
            310                     while(CurrentSize<ExtendedSize && *Read1++==*Read2++)
            311                     {
            312                         CurrentSize++;
            313                     }
            314                     if(CurrentSize>Record.Size)
            315                     {
            316                         Record.Compressed=true;
            317                         Record.Start=i;
            318                         Record.Size=CurrentSize;
            319                         if(CurrentSize==ExtendedSize)
            320                         {
            321                             break;
            322                         }
            323                     }
            324                 }
            325                 return Record;
            326             }
            327 
            328             // 1 <= byte count <= window size
            329             // 0 <= compressed index < window size
            330             // 2 <= compressed size <= window size
            331             // 1 <= uncompressed size <= window size
            332             VInt Compressor::CompressAndWrite(VInt ByteCount)
            333             {
            334                 VInt SelectedStart=-1;
            335                 VInt EncodedLength=-1;
            336                 if(ByteCount>DoubleMaxBlockSize)
            337                 {
            338                     ByteCount=DoubleMaxBlockSize;
            339                 }
            340 
            341                 VInt UncompressedBlockSize=0;
            342                 VInt CompressedBlockStart=0;
            343                 VInt CompressedBlockSize=0;
            344                 VInt MaxUncompressedSize=MaxBlockSize<ByteCount?MaxBlockSize:ByteCount;
            345                 while(UncompressedBlockSize<MaxUncompressedSize)
            346                 {
            347                     VInt ExtendedSize=ByteCount-UncompressedBlockSize;
            348                     if(ExtendedSize>MaxBlockSize)
            349                     {
            350                         ExtendedSize=MaxBlockSize;
            351                     }
            352 
            353                     VBuffer VirtualWindow=FWindow;
            354                     VInt VirtualWindowSize=FUsedWindowSize+UncompressedBlockSize;
            355                     if(VirtualWindowSize>WindowSize)
            356                     {
            357                         VirtualWindow+=VirtualWindowSize-WindowSize;
            358                         VirtualWindowSize=WindowSize;
            359                     }
            360 
            361                     CompressionRecord Record=TestCompression(VirtualWindow,VirtualWindowSize,ExtendedSize);
            362                     if(Record.Compressed)
            363                     {
            364                         CompressedBlockStart=Record.Start;
            365                         CompressedBlockSize=Record.Size;
            366                         break;
            367                     }
            368                     else
            369                     {
            370                         UncompressedBlockSize++;
            371                     }
            372                 }
            373 
            374                 if(UncompressedBlockSize)
            375                 {
            376                     FBitWriter->WriteBit(false);
            377                     FBitWriter->WriteNumber(UncompressedBlockSize-1,ByteCountBitCount);
            378                     for(VInt i=0;i<UncompressedBlockSize;i++)
            379                     {
            380                         FBitWriter->WriteNumber(FWindow[FUsedWindowSize+i],8);
            381                     }
            382                     FPosition+=UncompressedBlockSize;
            383                 }
            384                 if(CompressedBlockSize)
            385                 {
            386                     FBitWriter->WriteBit(true);
            387                     FBitWriter->WriteNumber(CompressedBlockSize-1,ByteCountBitCount);
            388                     FBitWriter->WriteNumber(CompressedBlockStart,ByteIndexBitCount);
            389                     FPosition+=CompressedBlockSize;
            390                 }
            391 
            392                 ByteCount=UncompressedBlockSize+CompressedBlockSize;
            393                 FUsedWindowSize+=ByteCount;
            394                 if(FUsedWindowSize>WindowSize)
            395                 {
            396                     VInt Remain=FUsedWindowSize-WindowSize;
            397                     VInt CopySize=FUsedFullWindowSize-Remain;
            398 
            399                     memmove(FWindow,FWindow+Remain,CopySize);
            400                     FUsedWindowSize=WindowSize;
            401                     FWindowStartPosition+=Remain;
            402                     FUsedFullWindowSize=CopySize;
            403                 }
            404                 return ByteCount;
            405             }
            406 
            407             Compressor::Compressor(VInt WindowSizeLevel):AlgorithmBase(WindowSizeLevel)
            408             {
            409                 FBitWriter=0;
            410                 FUsedFullWindowSize=0;
            411             }
            412 
            413             Compressor::~Compressor()
            414             {
            415                 while(FUsedFullWindowSize>FUsedWindowSize)
            416                 {
            417                     VInt Size=CompressAndWrite(FUsedFullWindowSize-FUsedWindowSize);
            418                     if(Size==0)
            419                     {
            420                         break;
            421                     }
            422                 }
            423                 SetStream(0);
            424             }
            425 
            426             void Compressor::SetStream(IVL_Stream* Stream)
            427             {
            428                 if(FBitWriter)
            429                 {
            430                     delete FBitWriter;
            431                     FBitWriter=0;
            432                 }
            433                 if(Stream)
            434                 {
            435                     FBitWriter=new VL_BitWriter(Stream,false);
            436                 }
            437             }
            438 
            439             VInt Compressor::Write(VPointer Data , VInt ByteCount)
            440             {
            441                 VInt WrittenCount=0;
            442                 VBuffer DataBuffer=(VBuffer)Data;
            443                 while(WrittenCount<ByteCount)
            444                 {
            445                     VInt CopySize=WindowSize*3-FUsedFullWindowSize;
            446                     if(CopySize)
            447                     {
            448                         VInt DataSize=ByteCount-WrittenCount;
            449                         if(CopySize>DataSize)
            450                         {
            451                             CopySize=DataSize;
            452                         }
            453                         memcpy(FWindow+FUsedFullWindowSize,DataBuffer,CopySize);
            454                         DataBuffer+=CopySize;
            455                         FUsedFullWindowSize+=CopySize;
            456                         WrittenCount+=CopySize;
            457                     }
            458 
            459                     VInt Size=CompressAndWrite(FUsedFullWindowSize-FUsedWindowSize);
            460                     if(Size==0)
            461                     {
            462                         break;
            463                     }
            464                 }
            465                 return WrittenCount;
            466             }
            467 
            468 /*********************************************************************************************************
            469 LZ77Algorithms::Decompressor
            470 *********************************************************************************************************/
            471 
            472             VInt Decompressor::DecompressBlock()
            473             {
            474                 VBool BlockCompressed=false;
            475                 VUInt BlockSize=0;
            476                 if(!FReader->ReadBit(BlockCompressed))
            477                 {
            478                     return 0;
            479                 }
            480                 if(!FReader->ReadNumber(BlockSize,ByteCountBitCount))
            481                 {
            482                     return 0;
            483                 }
            484                 BlockSize++;
            485                 if(BlockCompressed)
            486                 {
            487                     VUInt BlockStart=0;
            488                     if(!FReader->ReadNumber(BlockStart,ByteIndexBitCount))
            489                     {
            490                         return 0;
            491                     }
            492                     VBuffer Dest=FWindow+FUsedWindowSize;
            493                     VBuffer Src=FWindow+BlockStart;
            494                     VInt Counter=BlockSize;
            495                     while(Counter--)
            496                     {
            497                         *Dest++=*Src++;
            498                     }
            499                 }
            500                 else
            501                 {
            502                     VUInt ByteContent=0;
            503                     VBuffer WriteEntry=FWindow+FUsedWindowSize;
            504                     VInt Counter=BlockSize;
            505                     while(Counter--)
            506                     {
            507                         if(!FReader->ReadNumber(ByteContent,8))
            508                         {
            509                             return 0;
            510                         }
            511                         *WriteEntry++=(VByte)ByteContent;
            512                     }
            513                 }
            514                 FUsedWindowSize+=BlockSize;
            515                 if(FUsedWindowSize>WindowSize)
            516                 {
            517                     VInt MoveSize=FUsedWindowSize-WindowSize;
            518                     memmove(FWindow,FWindow+MoveSize,WindowSize);
            519                     FUsedWindowSize=WindowSize;
            520                     FWindowStartPosition+=MoveSize;
            521                 }
            522                 return BlockSize;
            523             }
            524 
            525             Decompressor::Decompressor(VInt WindowSizeLevel):AlgorithmBase(WindowSizeLevel)
            526             {
            527                 FReader=0;
            528             }
            529 
            530             Decompressor::~Decompressor()
            531             {
            532                 SetStream(0);
            533             }
            534 
            535             void Decompressor::SetStream(IVL_Stream* Stream)
            536             {
            537                 if(FReader)
            538                 {
            539                     delete FReader;
            540                     FReader=0;
            541                 }
            542                 if(Stream)
            543                 {
            544                     FReader=new VL_BitReader(Stream,false);
            545                 }
            546             }
            547 
            548             VInt Decompressor::Read(VPointer Data , VInt ByteCount)
            549             {
            550                 VBuffer Buffer=(VBuffer)Data;
            551                 VInt WrittenCount=0;
            552                 while(WrittenCount<ByteCount)
            553                 {
            554                     if(FWindowStartPosition+FUsedWindowSize==FPosition)
            555                     {
            556                         if(DecompressBlock()==0)
            557                         {
            558                             break;
            559                         }
            560                     }
            561 
            562                     VInt NeedCount=ByteCount-WrittenCount;
            563                     VInt AllowSize=(VInt)(FWindowStartPosition+FUsedWindowSize-FPosition);
            564                     VInt ReadSize=NeedCount<AllowSize?NeedCount:AllowSize;
            565                     if(ReadSize)
            566                     {
            567                         memcpy(Buffer,FWindow+(FPosition-FWindowStartPosition),ReadSize);
            568                         WrittenCount+=ReadSize;
            569                         Buffer+=ReadSize;
            570                         FPosition+=ReadSize;
            571                     }
            572                     else
            573                     {
            574                         break;
            575                     }
            576                 }
            577                 return WrittenCount;
            578             }
            579 
            580         }
            581 
            582     }
            583 }
            posted on 2009-01-06 23:35 陳梓瀚(vczh) 閱讀(3026) 評論(6)  編輯 收藏 引用 所屬分類: C++

            評論:
            # re: 修改后的LZ77壓縮解壓源碼 2009-01-08 01:06 | cppfan
            曲高和寡~  回復(fù)  更多評論
              
            # re: 修改后的LZ77壓縮解壓源碼 2011-06-10 01:48 | magina3
            你好,看了你的博客,感覺相當(dāng)良好,最近在做一個項目,目標(biāo)設(shè)備需要使用lz77算法壓縮后才發(fā)給他,在網(wǎng)上找了很多資料,發(fā)現(xiàn)很多版本,由于時間有限,沒有深入研究,想請教一下你,你對這些參數(shù)的修改,和lz77其他版本的解壓程序是兼容的嗎,其他版本能正確解壓嗎?  回復(fù)  更多評論
              
            # re: 修改后的LZ77壓縮解壓源碼 2011-06-10 04:48 | 陳梓瀚(vczh)
            @magina3
            不兼容,不能。我只是表達(dá)了主要思想,至于如何兼容其他人的格式,你得去查一些資料。譬如說C#的GzipStream似乎就是跟別人兼容的。  回復(fù)  更多評論
              
            # re: 修改后的LZ77壓縮解壓源碼 2011-06-12 17:20 | magina3
            @陳梓瀚(vczh)
            謝謝你的回答  回復(fù)  更多評論
              
            # re: 修改后的LZ77壓縮解壓源碼 2011-06-12 17:27 | magina3
            不知道你方不方便解答一下,目標(biāo)設(shè)備既然要求發(fā)送數(shù)據(jù)是Lz77壓縮的,那么我需要知道些什么參數(shù)才能保證我使用的lz77壓縮程序生成的數(shù)據(jù)目標(biāo)設(shè)備能夠正確解壓呢?  回復(fù)  更多評論
              
            # re: 修改后的LZ77壓縮解壓源碼 2011-06-13 09:05 | 陳梓瀚(vczh)
            @magina3
            閱讀目標(biāo)設(shè)備的文檔  回復(fù)  更多評論
              
            亚洲一区二区三区日本久久九| 成人午夜精品久久久久久久小说| 欧美亚洲国产精品久久久久| 久久夜色精品国产亚洲| 亚洲精品无码久久久久去q| 大伊人青草狠狠久久| 久久久久国产视频电影| 亚洲午夜久久久久妓女影院| 精品久久久久久中文字幕| 欧美大战日韩91综合一区婷婷久久青草 | 三级三级久久三级久久| 久久精品国产99久久久| 亚洲精品tv久久久久久久久久| 久久综合国产乱子伦精品免费| 国产成人综合久久久久久| 色综合久久综合中文综合网| 久久精品中文字幕一区| 国产精品久久久久久福利漫画| 综合久久一区二区三区 | 久久精品这里只有精99品| 精品久久久久香蕉网| 久久精品人妻中文系列| 久久久久国色AV免费观看| 精品免费久久久久久久| 久久婷婷国产剧情内射白浆| 国产精品免费久久久久久久久| 久久夜色精品国产欧美乱| 一本色道久久88—综合亚洲精品| 超级碰久久免费公开视频| 亚洲国产成人久久精品动漫| 久久亚洲精品无码AV红樱桃| 国产色综合久久无码有码| 久久笫一福利免费导航 | 99久久免费国产精精品| 亚洲va国产va天堂va久久| 狠狠色丁香久久婷婷综合蜜芽五月| 精品久久人人爽天天玩人人妻 | 久久久久久国产a免费观看不卡| 九九久久精品无码专区| 久久精品二区| 少妇久久久久久被弄到高潮|