Removed RAR support due to licensing conflicts with the GNU GPL.
This commit is contained in:
parent
bdbda96961
commit
46bbb9be39
|
@ -201,14 +201,6 @@
|
|||
RelativePath=".\fex\Gzip_Reader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\Rar_Extractor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\Rar_Extractor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\Single_File_Extractor.cpp"
|
||||
>
|
||||
|
@ -217,14 +209,6 @@
|
|||
RelativePath=".\fex\Single_File_Extractor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\unrarlib.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\unrarlib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fex\unzip.cpp"
|
||||
>
|
||||
|
@ -301,46 +285,6 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="rar"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\unrar\archive.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\model.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\Rar_Extractor_Impl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\rarmisc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\rarvm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\suballoc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\unpack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\unpack15.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unrar\unpack20.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
#if FEX_ENABLE_RAR
|
||||
|
||||
#include "Rar_Extractor.h"
|
||||
|
||||
#include "unrar/rar.hpp"
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
const char end_of_rar [] = "Unexpected end of RAR archive";
|
||||
|
||||
Rar_Extractor::Rar_Extractor() : File_Extractor( fex_rar_type )
|
||||
{
|
||||
impl = 0;
|
||||
}
|
||||
|
||||
static File_Extractor* new_rar() { return BLARGG_NEW Rar_Extractor; }
|
||||
|
||||
fex_type_t_ const fex_rar_type [1] = {{ "RAR", &new_rar }};
|
||||
|
||||
void Rar_Extractor::close_()
|
||||
{
|
||||
delete impl;
|
||||
impl = 0;
|
||||
}
|
||||
|
||||
Rar_Extractor::~Rar_Extractor() { close(); }
|
||||
|
||||
blargg_err_t Rar_Extractor::open_()
|
||||
{
|
||||
RETURN_ERR( file().seek( 0 ) );
|
||||
|
||||
CHECK_ALLOC( impl = BLARGG_NEW Rar_Extractor_Impl( &file() ) );
|
||||
|
||||
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
|
||||
|
||||
impl->Unp.Init( 0 );
|
||||
|
||||
if ( !impl->arc.IsArchive() )
|
||||
return fex_wrong_file_type;
|
||||
|
||||
RETURN_ERR( impl->arc.IsArchive2() );
|
||||
|
||||
index = -1;
|
||||
can_extract = true;
|
||||
|
||||
return next_item();
|
||||
}
|
||||
|
||||
blargg_err_t Rar_Extractor::rewind_()
|
||||
{
|
||||
assert( impl );
|
||||
close_();
|
||||
return open_();
|
||||
}
|
||||
|
||||
blargg_err_t Rar_Extractor::next_item()
|
||||
{
|
||||
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
|
||||
|
||||
index++;
|
||||
for ( ;; impl->arc.SeekToNext() )
|
||||
{
|
||||
blargg_err_t err = impl->arc.ReadHeader();
|
||||
if ( err == end_of_rar )
|
||||
{
|
||||
set_done();
|
||||
break;
|
||||
}
|
||||
if ( err )
|
||||
return err;
|
||||
|
||||
HEADER_TYPE type = (HEADER_TYPE) impl->arc.GetHeaderType();
|
||||
if ( type == ENDARC_HEAD )
|
||||
{
|
||||
// no files beyond this point
|
||||
set_done();
|
||||
break;
|
||||
}
|
||||
|
||||
// skip non-files
|
||||
if ( type != FILE_HEAD )
|
||||
{
|
||||
if ( type != NEWSUB_HEAD && type != PROTECT_HEAD )
|
||||
dprintf( "Skipping unknown RAR block type: %X\n", (int) type );
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip label
|
||||
if ( impl->arc.NewLhd.HostOS <= HOST_WIN32 && (impl->arc.NewLhd.FileAttr & 8) )
|
||||
continue;
|
||||
|
||||
// skip links
|
||||
if ( (impl->arc.NewLhd.FileAttr & 0xF000) == 0xA000 )
|
||||
continue;
|
||||
|
||||
// skip directories
|
||||
if ( (impl->arc.NewLhd.Flags & LHD_WINDOWMASK) == LHD_DIRECTORY )
|
||||
continue;
|
||||
|
||||
set_info( impl->arc.NewLhd.UnpSize, impl->arc.NewLhd.FileName );
|
||||
break;
|
||||
}
|
||||
|
||||
extracted = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
blargg_err_t Rar_Extractor::next_()
|
||||
{
|
||||
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
|
||||
|
||||
if ( !extracted && impl->arc.Solid )
|
||||
{
|
||||
if ( is_scan_only() )
|
||||
{
|
||||
can_extract = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// must extract every file in a solid archive
|
||||
Null_Writer out;
|
||||
RETURN_ERR( impl->extract( out, false ) );
|
||||
}
|
||||
}
|
||||
|
||||
impl->arc.SeekToNext();
|
||||
return next_item();
|
||||
}
|
||||
|
||||
blargg_err_t Rar_Extractor::extract( Data_Writer& out )
|
||||
{
|
||||
if ( !impl || extracted )
|
||||
return Data_Reader::eof_error;
|
||||
|
||||
CHECK_ALLOC( !setjmp( impl->jmp_env ) );
|
||||
|
||||
if ( !can_extract )
|
||||
{
|
||||
int saved_index = index;
|
||||
|
||||
RETURN_ERR( rewind_() );
|
||||
scan_only( false );
|
||||
while ( index < saved_index )
|
||||
{
|
||||
if ( done() )
|
||||
return "Corrupt RAR archive";
|
||||
RETURN_ERR( next_() );
|
||||
}
|
||||
assert( can_extract );
|
||||
}
|
||||
extracted = true;
|
||||
|
||||
impl->write_error = 0;
|
||||
RETURN_ERR( impl->extract( out ) );
|
||||
return impl->write_error;
|
||||
}
|
||||
|
||||
// Rar_Extractor_Impl
|
||||
|
||||
void Rar_Extractor_Impl::Seek( long n )
|
||||
{
|
||||
if ( reader->seek( n ) )
|
||||
check( false );
|
||||
}
|
||||
|
||||
long Rar_Extractor_Impl::Tell() { return reader->tell(); }
|
||||
|
||||
long Rar_Extractor_Impl::Read( void* p, long n ) { return reader->read_avail( p, n ); }
|
||||
|
||||
long Rar_Extractor_Impl::Size() { return reader->size(); }
|
||||
|
||||
void Rar_Extractor_Impl::UnpWrite( byte const* out, uint count )
|
||||
{
|
||||
if ( !write_error )
|
||||
write_error = writer->write( out, count );
|
||||
if ( MaintainCRC )
|
||||
{
|
||||
if ( arc.OldFormat )
|
||||
UnpFileCRC = OldCRC( (ushort) UnpFileCRC, out, count );
|
||||
else
|
||||
UnpFileCRC = CRC( UnpFileCRC, out, count );
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
// RAR archive extractor
|
||||
|
||||
// File_Extractor 0.4.2
|
||||
#ifndef RAR_EXTRACTOR_H
|
||||
#define RAR_EXTRACTOR_H
|
||||
|
||||
#include "File_Extractor.h"
|
||||
|
||||
class Rar_Extractor : public File_Extractor {
|
||||
public:
|
||||
Rar_Extractor();
|
||||
~Rar_Extractor();
|
||||
blargg_err_t extract( Data_Writer& );
|
||||
protected:
|
||||
blargg_err_t open_();
|
||||
blargg_err_t next_();
|
||||
blargg_err_t rewind_();
|
||||
void close_();
|
||||
private:
|
||||
class Rar_Extractor_Impl* impl;
|
||||
int index;
|
||||
bool can_extract;
|
||||
bool extracted;
|
||||
blargg_err_t next_item();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||
// File_Extractor 0.4.2. http://www.slack.net/~ant/
|
||||
|
||||
#include "unrarlib.h"
|
||||
|
||||
#include "File_Extractor.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
// log error message to stderr when debugging
|
||||
inline const char* log_error( const char* str )
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if ( str )
|
||||
fprintf( stderr, "unrarlib Error: %s\n", str );
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
int urarlib_list( const char* path, ArchiveList_struct** list )
|
||||
{
|
||||
ArchiveList_struct** tail = list;
|
||||
int count = 0;
|
||||
*list = 0;
|
||||
|
||||
File_Extractor* fex = 0;
|
||||
if ( log_error( fex_open( path, &fex ) ) )
|
||||
goto error;
|
||||
|
||||
fex->scan_only(); // significantly faster for solid archives
|
||||
|
||||
while ( !fex->done() )
|
||||
{
|
||||
ArchiveList_struct* item = (ArchiveList_struct*) calloc( sizeof *item, 1 );
|
||||
if ( !item )
|
||||
goto error;
|
||||
|
||||
// insert at end
|
||||
*tail = item;
|
||||
item->next = 0;
|
||||
tail = &item->next;
|
||||
count++;
|
||||
|
||||
item->item.NameSize = strlen( fex->name() );
|
||||
item->item.Name = (char*) malloc( item->item.NameSize + 1 );
|
||||
if ( !item->item.Name )
|
||||
goto error;
|
||||
|
||||
strcpy( item->item.Name, fex->name() );
|
||||
item->item.UnpSize = fex->size();
|
||||
|
||||
if ( log_error( fex->next() ) )
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( 0 )
|
||||
{
|
||||
error:
|
||||
urarlib_freelist( *list );
|
||||
*list = 0;
|
||||
count = 0;
|
||||
}
|
||||
delete fex;
|
||||
return count;
|
||||
}
|
||||
|
||||
void urarlib_freelist( ArchiveList_struct* node )
|
||||
{
|
||||
while ( node )
|
||||
{
|
||||
ArchiveList_struct* next = node->next;
|
||||
free( node->item.Name );
|
||||
free( node );
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
int urarlib_get( void* output, unsigned long* size, const char* filename,
|
||||
const char* path, const char* password )
|
||||
{
|
||||
assert( !password ); // password not supported
|
||||
|
||||
*(void**) output = 0;
|
||||
*size = 0;
|
||||
void* buf = 0;
|
||||
|
||||
File_Extractor* fex = 0;
|
||||
if ( log_error( fex_open( path, &fex ) ) )
|
||||
goto error;
|
||||
|
||||
while ( !fex->done() )
|
||||
{
|
||||
if ( !strcmp( fex->name(), filename ) )
|
||||
{
|
||||
buf = malloc( fex->size() );
|
||||
if ( !buf || log_error( fex->read( buf, fex->size() ) ) )
|
||||
goto error;
|
||||
|
||||
*(void**) output = buf;
|
||||
*size = fex->size();
|
||||
delete fex;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( log_error( fex->next() ) )
|
||||
goto error;
|
||||
}
|
||||
// not found
|
||||
error:
|
||||
free( buf );
|
||||
delete fex;
|
||||
return false;
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/* Accesses file archives using unrarlib 0.4.0 (UniquE RAR File Library) interface.
|
||||
With this you can use File_Extractor in place of unrarlib with minimal
|
||||
changes to your code. If you're writing new code, use the fex.h interface. */
|
||||
|
||||
/* File_Extractor 0.4.2 */
|
||||
#ifndef URARLIB_H
|
||||
#define URARLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct RAR20_archive_entry
|
||||
{
|
||||
/* Only Name, NameSize, and UnpSize are valid; all other fields are set to zero */
|
||||
char* Name;
|
||||
unsigned short NameSize;
|
||||
unsigned long PackSize;
|
||||
unsigned long UnpSize;
|
||||
unsigned char HostOS;
|
||||
unsigned long FileCRC;
|
||||
unsigned long FileTime;
|
||||
unsigned char UnpVer;
|
||||
unsigned char Method;
|
||||
unsigned long FileAttr;
|
||||
};
|
||||
|
||||
typedef struct ArchiveList_struct
|
||||
{
|
||||
struct RAR20_archive_entry item;
|
||||
struct ArchiveList_struct* next; /* next entry in list, or NULL if end of list */
|
||||
|
||||
} ArchiveList_struct;
|
||||
|
||||
/* Allocate and set *list_out to first node of linked list of files from file archive at
|
||||
'archive_path' and return number of items in list. Use urarlib_freelist() to free memory
|
||||
used by the list. */
|
||||
int urarlib_list( const char* archive_path, ArchiveList_struct** list_out );
|
||||
|
||||
/* Extract 'filename' from a file archive at 'archive_path' into internal buffer.
|
||||
Sets *buffer_out to beginning of data and *size_out to number of bytes extracted.
|
||||
Returns true if successful otherwise false. Password is not supported (must be NULL).
|
||||
Caller must free() returned buffer when done with it.
|
||||
Note: buffer_out is treated as void**, but declared as void* to match original urarlib.h. */
|
||||
int urarlib_get( void* buffer_out, unsigned long* size_out, const char* filename,
|
||||
const char* archive_path, const char* password );
|
||||
|
||||
/* Free memory used by list of nodes returned by urarlib_list(). Pointer must be that
|
||||
returned by urarlib_list() (that is, the first node in the list). */
|
||||
void urarlib_freelist( ArchiveList_struct* list );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,105 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
Rar_Extractor_Impl::Rar_Extractor_Impl( File_Reader* in ) :
|
||||
reader( in ),
|
||||
arc( this ),
|
||||
Unp( this, this ),
|
||||
Buffer( this )
|
||||
{
|
||||
first_file = true;
|
||||
InitCRC();
|
||||
}
|
||||
|
||||
void rar_out_of_memory( Rar_Error_Handler* eh )
|
||||
{
|
||||
longjmp( eh->jmp_env, 1 );
|
||||
}
|
||||
|
||||
int Rar_Extractor_Impl::UnpRead( byte* out, uint count )
|
||||
{
|
||||
if ( count <= 0 )
|
||||
return 0;
|
||||
|
||||
if ( count > (uint) UnpPackedSize )
|
||||
count = UnpPackedSize;
|
||||
|
||||
long result = Read( out, count );
|
||||
if ( result >= 0 )
|
||||
UnpPackedSize -= result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Rar_Extractor_Impl::UnstoreFile( Int64 DestUnpSize )
|
||||
{
|
||||
Buffer.Alloc( 0x10000 );
|
||||
while ( true )
|
||||
{
|
||||
unsigned int result = UnpRead( &Buffer[0], Buffer.Size() );
|
||||
if ( result == 0 || (int) result == -1 )
|
||||
break;
|
||||
|
||||
result = ((Int64) result < DestUnpSize ? result : int64to32( DestUnpSize ));
|
||||
UnpWrite( &Buffer[0], result );
|
||||
if ( DestUnpSize >= 0 )
|
||||
DestUnpSize -= result;
|
||||
}
|
||||
Buffer.Reset();
|
||||
}
|
||||
|
||||
const char* Rar_Extractor_Impl::extract( Data_Writer& rar_writer, bool check_crc )
|
||||
{
|
||||
assert( arc.GetHeaderType() == FILE_HEAD );
|
||||
|
||||
if ( arc.NewLhd.Flags & (LHD_SPLIT_AFTER | LHD_SPLIT_BEFORE) )
|
||||
return "Segmented RAR not supported";
|
||||
|
||||
if ( arc.NewLhd.Flags & LHD_PASSWORD )
|
||||
return "Encrypted RAR archive not supported";
|
||||
|
||||
if ( arc.NewLhd.UnpVer < 13 || arc.NewLhd.UnpVer > UNP_VER )
|
||||
return "RAR file uses an unsupported format (too old or too recent)";
|
||||
|
||||
Seek( arc.NextBlockPos - arc.NewLhd.FullPackSize );
|
||||
|
||||
UnpFileCRC = arc.OldFormat ? 0 : 0xFFFFFFFF;
|
||||
PackedCRC = 0xFFFFFFFF;
|
||||
UnpPackedSize = arc.NewLhd.FullPackSize;
|
||||
MaintainCRC = check_crc;
|
||||
this->writer = &rar_writer;
|
||||
|
||||
if ( arc.NewLhd.Method == 0x30 )
|
||||
{
|
||||
UnstoreFile( arc.NewLhd.FullUnpSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
Unp.SetDestSize( arc.NewLhd.FullUnpSize );
|
||||
if ( arc.NewLhd.UnpVer <= 15 )
|
||||
Unp.DoUnpack( 15, arc.Solid && !first_file );
|
||||
else
|
||||
Unp.DoUnpack( arc.NewLhd.UnpVer, arc.NewLhd.Flags & LHD_SOLID);
|
||||
}
|
||||
|
||||
first_file = false;
|
||||
|
||||
arc.SeekToNext();
|
||||
|
||||
if ( check_crc )
|
||||
{
|
||||
unsigned long correct = arc.NewLhd.FileCRC;
|
||||
if ( !arc.OldFormat )
|
||||
correct = ~correct;
|
||||
|
||||
if ( (UnpFileCRC ^ correct) & 0xFFFFFFFF )
|
||||
return "CRC error";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef RAR_EXTRACTOR_IMPL_H
|
||||
#define RAR_EXTRACTOR_IMPL_H
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
extern const char end_of_rar [];
|
||||
|
||||
class Data_Writer;
|
||||
class File_Reader;
|
||||
|
||||
class Rar_Extractor_Impl : public Rar_Allocator {
|
||||
public:
|
||||
void Seek( long );
|
||||
long Tell();
|
||||
long Read( void*, long );
|
||||
long Size();
|
||||
|
||||
int UnpRead( byte*, uint );
|
||||
void UnpWrite( byte const*, uint );
|
||||
jmp_buf jmp_env;
|
||||
|
||||
private:
|
||||
File_Reader* reader;
|
||||
Archive arc;
|
||||
bool first_file;
|
||||
Unpack Unp;
|
||||
Rar_Array<byte> Buffer;
|
||||
const char* write_error; // once write error occurs, no more writes are made
|
||||
Data_Writer* writer;
|
||||
Int64 UnpPackedSize;
|
||||
uint UnpFileCRC,PackedCRC;
|
||||
bool MaintainCRC;
|
||||
|
||||
const char* extract( Data_Writer&, bool check_crc = 1 );
|
||||
|
||||
Rar_Extractor_Impl( File_Reader* in );
|
||||
void UnstoreFile( Int64 );
|
||||
|
||||
friend class Rar_Extractor;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,371 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef check
|
||||
#define check( expr ) ((void) 0)
|
||||
#endif
|
||||
|
||||
Archive::Archive( Rar_Extractor_Impl* impl_ ) : NewLhd( impl_ ), SubHead( impl_ ), Raw( impl_ )
|
||||
{
|
||||
impl = impl_;
|
||||
OldFormat=false;
|
||||
Solid=false;
|
||||
LastReadBlock=0;
|
||||
|
||||
CurBlockPos=0;
|
||||
NextBlockPos=0;
|
||||
|
||||
memset(&NewMhd,0,sizeof(NewMhd));
|
||||
NewMhd.HeadType=MAIN_HEAD;
|
||||
NewMhd.HeadSize=SIZEOF_NEWMHD;
|
||||
HeaderCRC=0;
|
||||
}
|
||||
|
||||
bool Archive::IsSignature(byte *D)
|
||||
{
|
||||
OldFormat = false;
|
||||
if ( D [0] != 0x52 )
|
||||
return false;
|
||||
|
||||
if ( D [1] == 0x45 && D [2] == 0x7E && D [3] == 0x5E )
|
||||
{
|
||||
OldFormat = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( D [1] == 0x61 && D [2] == 0x72 && D [3] == 0x21 &&
|
||||
D [4] == 0x1A && D [5] == 0x07 && D [6] == 0x00)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Archive::IsArchive()
|
||||
{
|
||||
if ( impl->Read( MarkHead.Mark,SIZEOF_MARKHEAD ) != SIZEOF_MARKHEAD )
|
||||
return 0;
|
||||
|
||||
if ( !IsSignature( MarkHead.Mark ) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* Archive::IsArchive2()
|
||||
{
|
||||
if (OldFormat)
|
||||
impl->Seek(0);
|
||||
|
||||
const char* error = ReadHeader();
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
SeekToNext();
|
||||
if ( OldFormat )
|
||||
{
|
||||
NewMhd.Flags = OldMhd.Flags & 0x3f;
|
||||
NewMhd.HeadSize = OldMhd.HeadSize;
|
||||
}
|
||||
else if ( HeaderCRC != NewMhd.HeadCRC )
|
||||
{
|
||||
return "RAR header CRC is wrong";
|
||||
}
|
||||
|
||||
if ( NewMhd.Flags & MHD_VOLUME )
|
||||
return "Split RAR files are not supported";
|
||||
|
||||
if ( NewMhd.Flags & MHD_PASSWORD )
|
||||
return "Encrypted RAR files are not supported";
|
||||
|
||||
Solid = (NewMhd.Flags & MHD_SOLID) != 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Archive::SeekToNext()
|
||||
{
|
||||
impl->Seek( NextBlockPos );
|
||||
}
|
||||
|
||||
// RawRead
|
||||
|
||||
RawRead::RawRead( Rar_Extractor_Impl* impl_ ) : Data( impl_ )
|
||||
{
|
||||
impl = impl_;
|
||||
ReadPos = 0;
|
||||
DataSize = 0;
|
||||
}
|
||||
|
||||
void RawRead::Reset()
|
||||
{
|
||||
check( ReadPos == DataSize );
|
||||
ReadPos = 0;
|
||||
DataSize = 0;
|
||||
Data.Reset();
|
||||
}
|
||||
|
||||
void RawRead::Read( int count )
|
||||
{
|
||||
if ( count )
|
||||
{
|
||||
Data.Alloc( DataSize + count );
|
||||
DataSize += impl->Read( &Data [DataSize], count );
|
||||
}
|
||||
}
|
||||
|
||||
void RawRead::get8( byte& out )
|
||||
{
|
||||
out = Data [ReadPos];
|
||||
ReadPos++;
|
||||
}
|
||||
|
||||
void RawRead::get16( ushort& out )
|
||||
{
|
||||
out = Data [ReadPos] + (Data [ReadPos + 1] << 8);
|
||||
ReadPos += 2;
|
||||
}
|
||||
|
||||
void RawRead::get32( uint& out )
|
||||
{
|
||||
out=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
|
||||
(Data[ReadPos+3]<<24);
|
||||
ReadPos+=4;
|
||||
}
|
||||
|
||||
void RawRead::Get( byte* out, int count )
|
||||
{
|
||||
memcpy( out, &Data [ReadPos], count );
|
||||
ReadPos += count;
|
||||
}
|
||||
|
||||
uint RawRead::GetCRC( bool partial )
|
||||
{
|
||||
uint crc = 0xFFFFFFFF;
|
||||
if ( DataSize > 2 )
|
||||
crc = CRC( crc, &Data[2], (partial ? ReadPos : DataSize) - 2 );
|
||||
return ~crc & 0xFFFF;
|
||||
}
|
||||
|
||||
// Archive::ReadHeader()
|
||||
|
||||
const char* Archive::ReadHeader()
|
||||
{
|
||||
CurBlockPos = impl->Tell();
|
||||
|
||||
if ( OldFormat )
|
||||
return ReadOldHeader();
|
||||
|
||||
Raw.Reset();
|
||||
|
||||
Raw.Read( SIZEOF_SHORTBLOCKHEAD );
|
||||
if ( Raw.Size() == 0 )
|
||||
{
|
||||
Int64 ArcSize = impl->Size();
|
||||
if ( CurBlockPos > ArcSize || NextBlockPos > ArcSize )
|
||||
return "RAR file is missing data at the end";
|
||||
return end_of_rar;
|
||||
}
|
||||
check( Raw.Size() == SIZEOF_SHORTBLOCKHEAD );
|
||||
|
||||
Raw.get16( ShortBlock.HeadCRC );
|
||||
byte HeadType;
|
||||
Raw.get8( HeadType );
|
||||
ShortBlock.HeadType=(HEADER_TYPE)HeadType;
|
||||
Raw.get16( ShortBlock.Flags );
|
||||
Raw.get16( ShortBlock.HeadSize );
|
||||
if ( ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
|
||||
return "CRC error in RAR file";
|
||||
|
||||
if ( ShortBlock.HeadType==COMM_HEAD)
|
||||
Raw.Read( SIZEOF_COMMHEAD-SIZEOF_SHORTBLOCKHEAD );
|
||||
else
|
||||
if ( ShortBlock.HeadType==MAIN_HEAD && (ShortBlock.Flags & MHD_COMMENT)!=0)
|
||||
Raw.Read( SIZEOF_NEWMHD-SIZEOF_SHORTBLOCKHEAD );
|
||||
else
|
||||
Raw.Read( ShortBlock.HeadSize-SIZEOF_SHORTBLOCKHEAD );
|
||||
|
||||
NextBlockPos = CurBlockPos + ShortBlock.HeadSize;
|
||||
|
||||
switch ( ShortBlock.HeadType )
|
||||
{
|
||||
case MAIN_HEAD:
|
||||
*(BaseBlock*)&NewMhd=ShortBlock;
|
||||
Raw.get16( NewMhd.HighPosAV );
|
||||
Raw.get32( NewMhd.PosAV );
|
||||
break;
|
||||
case ENDARC_HEAD:
|
||||
// ignore
|
||||
break;
|
||||
|
||||
case FILE_HEAD:
|
||||
case NEWSUB_HEAD:
|
||||
{
|
||||
FileHeader *hd=ShortBlock.HeadType==FILE_HEAD ? &NewLhd:&SubHead;
|
||||
*(BaseBlock*)hd=ShortBlock;
|
||||
Raw.get32( hd->PackSize );
|
||||
Raw.get32( hd->UnpSize );
|
||||
Raw.get8( hd->HostOS );
|
||||
Raw.get32( hd->FileCRC );
|
||||
Raw.get32( hd->FileTime );
|
||||
Raw.get8( hd->UnpVer );
|
||||
Raw.get8( hd->Method );
|
||||
Raw.get16( hd->NameSize );
|
||||
Raw.get32( hd->FileAttr );
|
||||
|
||||
hd->HighPackSize=hd->HighUnpSize=0;
|
||||
if (hd->Flags & LHD_LARGE)
|
||||
{
|
||||
Raw.get32( hd->HighPackSize );
|
||||
Raw.get32( hd->HighUnpSize );
|
||||
}
|
||||
|
||||
assert( hd->UnpSize != 0xFFFFFFFF );
|
||||
|
||||
if ( hd->HighPackSize || hd->HighUnpSize )
|
||||
return "Huge RAR archives not supported";
|
||||
|
||||
hd->FullPackSize = hd->PackSize;
|
||||
hd->FullUnpSize = hd->UnpSize;
|
||||
|
||||
char FileName[NM*4];
|
||||
int NameSize=Min(hd->NameSize,sizeof(FileName)-1 );
|
||||
Raw.Get((byte*)FileName,NameSize );
|
||||
FileName[NameSize]=0;
|
||||
|
||||
strncpy(hd->FileName,FileName,sizeof(hd->FileName) );
|
||||
hd->FileName[sizeof(hd->FileName)-1]=0;
|
||||
|
||||
if (hd->HeadType==NEWSUB_HEAD)
|
||||
{
|
||||
int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD;
|
||||
if (hd->Flags & LHD_SALT)
|
||||
DataSize-=SALT_SIZE;
|
||||
if (DataSize>0)
|
||||
{
|
||||
hd->SubData.Alloc(DataSize );
|
||||
Raw.Get(&hd->SubData[0],DataSize );
|
||||
//if ( !strcmp( hd->FileName, SUBHEAD_TYPE_RR ) )
|
||||
//byte *D=&hd->SubData[8];
|
||||
}
|
||||
}
|
||||
else if (hd->HeadType==FILE_HEAD)
|
||||
{
|
||||
hd->Flags &= ~LHD_UNICODE;
|
||||
|
||||
if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10))
|
||||
NewLhd.Flags|=LHD_DIRECTORY;
|
||||
|
||||
if (NewLhd.HostOS>=HOST_MAX)
|
||||
{
|
||||
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||
NewLhd.FileAttr=0x10;
|
||||
else
|
||||
NewLhd.FileAttr=0x20;
|
||||
}
|
||||
}
|
||||
|
||||
if (hd->Flags & LHD_SALT)
|
||||
Raw.Get(hd->Salt,SALT_SIZE );
|
||||
|
||||
if (hd->Flags & LHD_EXTTIME)
|
||||
{
|
||||
ushort Flags;
|
||||
Raw.get16( Flags );
|
||||
for (int I=0;I<4;I++)
|
||||
{
|
||||
uint rmode=Flags>>(3-I)*4;
|
||||
if ((rmode & 8)==0)
|
||||
continue;
|
||||
if (I!=0)
|
||||
{
|
||||
uint DosTime;
|
||||
Raw.get32( DosTime );
|
||||
}
|
||||
|
||||
// skip time info
|
||||
for ( int n = rmode & 3; n--; )
|
||||
{
|
||||
byte CurByte;
|
||||
Raw.get8( CurByte );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NextBlockPos += hd->FullPackSize;
|
||||
HeaderCRC = Raw.GetCRC( hd->Flags & LHD_COMMENT );
|
||||
if ( hd->HeadCRC != HeaderCRC )
|
||||
return "RAR file header CRC is incorrect";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (ShortBlock.Flags & LONG_BLOCK)
|
||||
{
|
||||
uint DataSize;
|
||||
Raw.get32( DataSize );
|
||||
NextBlockPos += DataSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
HeaderCRC = Raw.GetCRC( false );
|
||||
CurHeaderType = ShortBlock.HeadType;
|
||||
|
||||
if ( NextBlockPos <= CurBlockPos )
|
||||
return "CRC error in RAR block header";
|
||||
|
||||
return Raw.Size() ? NULL : end_of_rar;
|
||||
}
|
||||
|
||||
const char* Archive::ReadOldHeader()
|
||||
{
|
||||
Raw.Reset();
|
||||
if (CurBlockPos<=SFXSize)
|
||||
{
|
||||
Raw.Read(SIZEOF_OLDMHD );
|
||||
Raw.Get(OldMhd.Mark,4 );
|
||||
Raw.get16( OldMhd.HeadSize );
|
||||
Raw.get8( OldMhd.Flags );
|
||||
NextBlockPos=CurBlockPos+OldMhd.HeadSize;
|
||||
CurHeaderType=MAIN_HEAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldFileHeader OldLhd;
|
||||
Raw.Read(SIZEOF_OLDLHD );
|
||||
NewLhd.HeadType=FILE_HEAD;
|
||||
Raw.get32( NewLhd.PackSize );
|
||||
Raw.get32( NewLhd.UnpSize );
|
||||
Raw.get16( OldLhd.FileCRC );
|
||||
Raw.get16( NewLhd.HeadSize );
|
||||
Raw.get32( NewLhd.FileTime );
|
||||
Raw.get8( OldLhd.FileAttr );
|
||||
Raw.get8( OldLhd.Flags );
|
||||
Raw.get8( OldLhd.UnpVer );
|
||||
Raw.get8( OldLhd.NameSize );
|
||||
Raw.get8( OldLhd.Method );
|
||||
|
||||
NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
|
||||
NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
|
||||
NewLhd.Method=OldLhd.Method+0x30;
|
||||
NewLhd.NameSize=OldLhd.NameSize;
|
||||
NewLhd.FileAttr=OldLhd.FileAttr;
|
||||
NewLhd.FileCRC=OldLhd.FileCRC;
|
||||
NewLhd.FullPackSize=NewLhd.PackSize;
|
||||
NewLhd.FullUnpSize=NewLhd.UnpSize;
|
||||
|
||||
Raw.Read(OldLhd.NameSize );
|
||||
Raw.Get((byte*)NewLhd.FileName,OldLhd.NameSize );
|
||||
NewLhd.FileName[OldLhd.NameSize]=0;
|
||||
|
||||
if (Raw.Size()!=0)
|
||||
NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize;
|
||||
CurHeaderType=FILE_HEAD;
|
||||
}
|
||||
return (NextBlockPos > CurBlockPos && Raw.Size()) ? NULL : end_of_rar;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_ARCHIVE_
|
||||
#define _RAR_ARCHIVE_
|
||||
|
||||
class RawRead {
|
||||
private:
|
||||
Rar_Array<byte> Data;
|
||||
Rar_Extractor_Impl* impl;
|
||||
int DataSize;
|
||||
int ReadPos;
|
||||
public:
|
||||
RawRead( Rar_Extractor_Impl* );
|
||||
~RawRead() { Reset(); }
|
||||
void Reset();
|
||||
void Read(int Size);
|
||||
void get8( byte& out );
|
||||
void get16( ushort& out );
|
||||
void get32( uint& out );
|
||||
void Get(byte *Field,int Size);
|
||||
uint GetCRC( bool partial );
|
||||
int Size() {return DataSize;}
|
||||
};
|
||||
|
||||
class Archive {
|
||||
public:
|
||||
|
||||
Archive( Rar_Extractor_Impl* );
|
||||
int IsArchive();
|
||||
const char* IsArchive2();
|
||||
const char* ReadHeader();
|
||||
void SeekToNext();
|
||||
int GetHeaderType() {return(CurHeaderType);};
|
||||
|
||||
BaseBlock ShortBlock;
|
||||
MainHeader NewMhd;
|
||||
FileHeader NewLhd;
|
||||
FileHeader SubHead;
|
||||
|
||||
Int64 CurBlockPos;
|
||||
Int64 NextBlockPos;
|
||||
|
||||
bool OldFormat;
|
||||
bool Solid;
|
||||
enum { SFXSize = 0 }; // we don't support self-extracting archive data at the beginning
|
||||
ushort HeaderCRC;
|
||||
|
||||
private:
|
||||
RawRead Raw;
|
||||
Rar_Error_Handler* impl;
|
||||
|
||||
MarkHeader MarkHead;
|
||||
OldMainHeader OldMhd;
|
||||
|
||||
int LastReadBlock;
|
||||
int CurHeaderType;
|
||||
|
||||
bool IsSignature(byte *D);
|
||||
const char* ReadOldHeader();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_ARRAY_
|
||||
#define _RAR_ARRAY_
|
||||
|
||||
template <class T>
|
||||
class Rar_Array {
|
||||
public:
|
||||
Rar_Array( Rar_Error_Handler* eh )
|
||||
{
|
||||
error_handler = eh;
|
||||
CleanData();
|
||||
}
|
||||
Rar_Array( int Size, Rar_Error_Handler* );
|
||||
~Rar_Array() { free( Buffer ); }
|
||||
|
||||
T& operator [] ( int Item ) { return Buffer [Item]; }
|
||||
int Size() { return BufSize; }
|
||||
void Add(int Items);
|
||||
void Alloc(int Items);
|
||||
void Reset();
|
||||
void Push(T Item);
|
||||
|
||||
private:
|
||||
T *Buffer;
|
||||
int BufSize;
|
||||
int AllocSize;
|
||||
Rar_Error_Handler* error_handler;
|
||||
void CleanData()
|
||||
{
|
||||
Buffer = NULL;
|
||||
BufSize = 0;
|
||||
AllocSize = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
Rar_Array<T>::Rar_Array( int Size, Rar_Error_Handler* eh )
|
||||
{
|
||||
error_handler = eh;
|
||||
AllocSize=BufSize=Size;
|
||||
Buffer=(T *)malloc(sizeof(T)*Size);
|
||||
if (Buffer==NULL && BufSize!=0)
|
||||
rar_out_of_memory( error_handler );
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Rar_Array<T>::Add(int Items)
|
||||
{
|
||||
BufSize+=Items;
|
||||
if (BufSize>AllocSize)
|
||||
{
|
||||
int Suggested=AllocSize+AllocSize/4+32;
|
||||
|
||||
int NewSize = BufSize;
|
||||
if ( NewSize < Suggested )
|
||||
NewSize = Suggested;
|
||||
|
||||
Buffer=(T *)realloc(Buffer,NewSize*sizeof(T));
|
||||
if (Buffer==NULL)
|
||||
rar_out_of_memory( error_handler );
|
||||
AllocSize=NewSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void Rar_Array<T>::Alloc(int Items)
|
||||
{
|
||||
if ( Items > AllocSize )
|
||||
Add( Items - BufSize );
|
||||
else
|
||||
BufSize = Items;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void Rar_Array<T>::Reset()
|
||||
{
|
||||
free( Buffer );
|
||||
CleanData();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Rar_Array<T>::Push(T Item)
|
||||
{
|
||||
Add( 1 );
|
||||
(*this) [Size() - 1] = Item;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_HEADERS_
|
||||
#define _RAR_HEADERS_
|
||||
|
||||
#define SIZEOF_MARKHEAD 7
|
||||
#define SIZEOF_OLDMHD 7
|
||||
#define SIZEOF_NEWMHD 13
|
||||
#define SIZEOF_OLDLHD 21
|
||||
#define SIZEOF_NEWLHD 32
|
||||
#define SIZEOF_SHORTBLOCKHEAD 7
|
||||
#define SIZEOF_SUBBLOCKHEAD 14
|
||||
#define SIZEOF_COMMHEAD 13
|
||||
|
||||
#define UNP_VER 29
|
||||
|
||||
#define MHD_VOLUME 0x0001
|
||||
#define MHD_COMMENT 0x0002
|
||||
#define MHD_SOLID 0x0008
|
||||
#define MHD_PASSWORD 0x0080
|
||||
|
||||
#define LHD_SPLIT_BEFORE 0x0001
|
||||
#define LHD_SPLIT_AFTER 0x0002
|
||||
#define LHD_PASSWORD 0x0004
|
||||
#define LHD_COMMENT 0x0008
|
||||
#define LHD_SOLID 0x0010
|
||||
|
||||
#define LHD_WINDOWMASK 0x00e0
|
||||
#define LHD_DIRECTORY 0x00e0
|
||||
|
||||
#define LHD_LARGE 0x0100
|
||||
#define LHD_UNICODE 0x0200
|
||||
#define LHD_SALT 0x0400
|
||||
#define LHD_EXTTIME 0x1000
|
||||
|
||||
#define LONG_BLOCK 0x8000
|
||||
|
||||
enum HEADER_TYPE {
|
||||
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
|
||||
SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
|
||||
ENDARC_HEAD=0x7b
|
||||
};
|
||||
|
||||
enum HOST_SYSTEM {
|
||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||
HOST_BEOS=5,HOST_MAX
|
||||
};
|
||||
|
||||
struct OldMainHeader
|
||||
{
|
||||
byte Mark[4];
|
||||
ushort HeadSize;
|
||||
byte Flags;
|
||||
};
|
||||
|
||||
struct OldFileHeader
|
||||
{
|
||||
uint PackSize;
|
||||
uint UnpSize;
|
||||
ushort FileCRC;
|
||||
ushort HeadSize;
|
||||
uint FileTime;
|
||||
byte FileAttr;
|
||||
byte Flags;
|
||||
byte UnpVer;
|
||||
byte NameSize;
|
||||
byte Method;
|
||||
};
|
||||
|
||||
struct MarkHeader
|
||||
{
|
||||
byte Mark[7];
|
||||
};
|
||||
|
||||
struct BaseBlock
|
||||
{
|
||||
ushort HeadCRC;
|
||||
HEADER_TYPE HeadType;//byte
|
||||
ushort Flags;
|
||||
ushort HeadSize;
|
||||
};
|
||||
|
||||
struct BlockHeader:BaseBlock
|
||||
{
|
||||
union {
|
||||
uint DataSize;
|
||||
uint PackSize;
|
||||
};
|
||||
};
|
||||
|
||||
struct MainHeader:BlockHeader
|
||||
{
|
||||
ushort HighPosAV;
|
||||
uint PosAV;
|
||||
};
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
struct FileHeader:BlockHeader
|
||||
{
|
||||
uint UnpSize;
|
||||
byte HostOS;
|
||||
uint FileCRC;
|
||||
uint FileTime;
|
||||
byte UnpVer;
|
||||
byte Method;
|
||||
ushort NameSize;
|
||||
union {
|
||||
uint FileAttr;
|
||||
uint SubFlags;
|
||||
};
|
||||
uint HighPackSize;
|
||||
uint HighUnpSize;
|
||||
char FileName[NM];
|
||||
Rar_Array<byte> SubData;
|
||||
byte Salt[SALT_SIZE];
|
||||
|
||||
Int64 FullPackSize;
|
||||
Int64 FullUnpSize;
|
||||
|
||||
FileHeader( Rar_Error_Handler* eh ) : SubData( eh ) { }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,624 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
/****************************************************************************
|
||||
* This file is part of PPMd project *
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2000 *
|
||||
* Contents: model description and encoding/decoding routines *
|
||||
****************************************************************************/
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#include "suballoc_inl.h"
|
||||
|
||||
inline void RangeCoder::InitDecoder(Unpack *UnpackRead)
|
||||
{
|
||||
RangeCoder::UnpackRead=UnpackRead;
|
||||
|
||||
low=code=0;
|
||||
range=uint(-1);
|
||||
for (int i=0;i < 4;i++)
|
||||
code=(code << 8) | GetChar();
|
||||
}
|
||||
|
||||
inline unsigned int RangeCoder::GetChar() {
|
||||
return(UnpackRead->GetChar());
|
||||
}
|
||||
|
||||
inline int RangeCoder::GetCurrentCount() {
|
||||
return (code-low)/(range /= SubRange.scale);
|
||||
}
|
||||
|
||||
inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT) {
|
||||
return (code-low)/(range >>= SHIFT);
|
||||
}
|
||||
|
||||
inline void RangeCoder::Decode() {
|
||||
low += range*SubRange.LowCount;
|
||||
range *= SubRange.HighCount-SubRange.LowCount;
|
||||
}
|
||||
|
||||
const uint TOP = 1 << 24;
|
||||
const uint BOT = 1 << 15;
|
||||
|
||||
#define ARI_DEC_NORMALIZE(code,low,range,read) \
|
||||
{ \
|
||||
while ((low^(low+range))<TOP || range<BOT && ((range=-low&(BOT-1)),1)) \
|
||||
{ \
|
||||
code=(code << 8) | read->GetChar(); \
|
||||
range <<= 8; \
|
||||
low <<= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
|
||||
STATE& FirstState)
|
||||
{
|
||||
PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
|
||||
if ( pc )
|
||||
{
|
||||
pc->NumStats=1;
|
||||
pc->OneState=FirstState;
|
||||
pc->Suffix=this;
|
||||
pStats->Successor=pc;
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
ModelPPM::ModelPPM( Rar_Error_Handler* eh ) : SubAlloc( eh )
|
||||
{
|
||||
MinContext=NULL;
|
||||
MaxContext=NULL;
|
||||
MedContext=NULL;
|
||||
MaxMB = 0;
|
||||
}
|
||||
|
||||
void ModelPPM::RestartModelRare()
|
||||
{
|
||||
int i, k, m;
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
SubAlloc.InitSubAllocator();
|
||||
InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
|
||||
MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
|
||||
MinContext->Suffix=NULL;
|
||||
OrderFall=MaxOrder;
|
||||
MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
|
||||
FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
|
||||
for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
|
||||
{
|
||||
MinContext->U.Stats[i].Symbol=i;
|
||||
MinContext->U.Stats[i].Freq=1;
|
||||
MinContext->U.Stats[i].Successor=NULL;
|
||||
}
|
||||
|
||||
static const ushort InitBinEsc[]={
|
||||
0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
|
||||
};
|
||||
|
||||
for (i=0;i < 128;i++)
|
||||
for (k=0;k < 8;k++)
|
||||
for (m=0;m < 64;m += 8)
|
||||
BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
|
||||
for (i=0;i < 25;i++)
|
||||
for (k=0;k < 16;k++)
|
||||
SEE2Cont[i][k].init(5*i+10);
|
||||
}
|
||||
|
||||
|
||||
void ModelPPM::StartModelRare(int MaxOrder)
|
||||
{
|
||||
int i, k, m ,Step;
|
||||
EscCount=1;
|
||||
/*
|
||||
if (MaxOrder < 2)
|
||||
{
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
OrderFall=ModelPPM::MaxOrder;
|
||||
MinContext=MaxContext;
|
||||
while (MinContext->Suffix != NULL)
|
||||
{
|
||||
MinContext=MinContext->Suffix;
|
||||
OrderFall--;
|
||||
}
|
||||
FoundState=MinContext->U.Stats;
|
||||
MinContext=MaxContext;
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
ModelPPM::MaxOrder=MaxOrder;
|
||||
RestartModelRare();
|
||||
NS2BSIndx[0]=2*0;
|
||||
NS2BSIndx[1]=2*1;
|
||||
memset(NS2BSIndx+2,2*2,9);
|
||||
memset(NS2BSIndx+11,2*3,256-11);
|
||||
for (i=0;i < 3;i++)
|
||||
NS2Indx[i]=i;
|
||||
for (m=i, k=Step=1;i < 256;i++)
|
||||
{
|
||||
NS2Indx[i]=m;
|
||||
if ( !--k )
|
||||
{
|
||||
k = ++Step;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
memset(HB2Flag,0,0x40);
|
||||
memset(HB2Flag+0x40,0x08,0x100-0x40);
|
||||
DummySEE2Cont.Shift=PERIOD_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
void PPM_CONTEXT::rescale(ModelPPM *Model)
|
||||
{
|
||||
int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
|
||||
STATE* p1, * p;
|
||||
for (p=Model->FoundState;p != U.Stats;p--)
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
U.Stats->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
EscFreq=U.SummFreq-p->Freq;
|
||||
Adder=(Model->OrderFall != 0);
|
||||
U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
|
||||
do
|
||||
{
|
||||
EscFreq -= (++p)->Freq;
|
||||
U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
|
||||
if (p[0].Freq > p[-1].Freq)
|
||||
{
|
||||
STATE tmp=*(p1=p);
|
||||
do
|
||||
{
|
||||
p1[0]=p1[-1];
|
||||
} while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
|
||||
*p1=tmp;
|
||||
}
|
||||
} while ( --i );
|
||||
if (p->Freq == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
i++;
|
||||
} while ((--p)->Freq == 0);
|
||||
EscFreq += i;
|
||||
if ((NumStats -= i) == 1)
|
||||
{
|
||||
STATE tmp=*U.Stats;
|
||||
do
|
||||
{
|
||||
tmp.Freq-=(tmp.Freq >> 1);
|
||||
EscFreq>>=1;
|
||||
} while (EscFreq > 1);
|
||||
Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
|
||||
*(Model->FoundState=&OneState)=tmp; return;
|
||||
}
|
||||
}
|
||||
U.SummFreq += (EscFreq -= (EscFreq >> 1));
|
||||
int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
|
||||
if (n0 != n1)
|
||||
U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
|
||||
Model->FoundState=U.Stats;
|
||||
}
|
||||
|
||||
inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
|
||||
{
|
||||
STATE UpState;
|
||||
PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
|
||||
STATE * p, * ps[MAX_O], ** pps=ps;
|
||||
if ( !Skip )
|
||||
{
|
||||
*pps++ = FoundState;
|
||||
if ( !pc->Suffix )
|
||||
goto NO_LOOP;
|
||||
}
|
||||
if ( p1 )
|
||||
{
|
||||
p=p1;
|
||||
pc=pc->Suffix;
|
||||
goto LOOP_ENTRY;
|
||||
}
|
||||
do
|
||||
{
|
||||
pc=pc->Suffix;
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != FoundState->Symbol);
|
||||
}
|
||||
else
|
||||
p=&(pc->OneState);
|
||||
LOOP_ENTRY:
|
||||
if (p->Successor != UpBranch)
|
||||
{
|
||||
pc=p->Successor;
|
||||
break;
|
||||
}
|
||||
*pps++ = p;
|
||||
} while ( pc->Suffix );
|
||||
NO_LOOP:
|
||||
if (pps == ps)
|
||||
return pc;
|
||||
UpState.Symbol=*(byte*) UpBranch;
|
||||
UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((byte*) pc <= SubAlloc.pText)
|
||||
return(NULL);
|
||||
if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != UpState.Symbol);
|
||||
uint cf=p->Freq-1;
|
||||
uint s0=pc->U.SummFreq-pc->NumStats-cf;
|
||||
UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
|
||||
}
|
||||
else
|
||||
UpState.Freq=pc->OneState.Freq;
|
||||
do
|
||||
{
|
||||
pc = pc->createChild(this,*--pps,UpState);
|
||||
if ( !pc )
|
||||
return NULL;
|
||||
} while (pps != ps);
|
||||
return pc;
|
||||
}
|
||||
|
||||
inline void ModelPPM::UpdateModel()
|
||||
{
|
||||
STATE fs = *FoundState, *p = NULL;
|
||||
PPM_CONTEXT *pc, *Successor;
|
||||
uint ns1, ns, cf, sf, s0;
|
||||
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
|
||||
{
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((p=pc->U.Stats)->Symbol != fs.Symbol)
|
||||
{
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (p->Symbol != fs.Symbol);
|
||||
if (p[0].Freq >= p[-1].Freq)
|
||||
{
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
p--;
|
||||
}
|
||||
}
|
||||
if (p->Freq < MAX_FREQ-9)
|
||||
{
|
||||
p->Freq += 2;
|
||||
pc->U.SummFreq += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p=&(pc->OneState);
|
||||
p->Freq += (p->Freq < 32);
|
||||
}
|
||||
}
|
||||
if ( !OrderFall )
|
||||
{
|
||||
MinContext=MaxContext=FoundState->Successor=CreateSuccessors(true,p);
|
||||
if ( !MinContext )
|
||||
goto RESTART_MODEL;
|
||||
return;
|
||||
}
|
||||
*SubAlloc.pText++ = fs.Symbol;
|
||||
Successor = (PPM_CONTEXT*) SubAlloc.pText;
|
||||
if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
|
||||
goto RESTART_MODEL;
|
||||
if ( fs.Successor )
|
||||
{
|
||||
if ((byte*) fs.Successor <= SubAlloc.pText &&
|
||||
(fs.Successor=CreateSuccessors(false,p)) == NULL)
|
||||
goto RESTART_MODEL;
|
||||
if ( !--OrderFall )
|
||||
{
|
||||
Successor=fs.Successor;
|
||||
SubAlloc.pText -= (MaxContext != MinContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FoundState->Successor=Successor;
|
||||
fs.Successor=MinContext;
|
||||
}
|
||||
s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
|
||||
for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
|
||||
{
|
||||
if ((ns1=pc->NumStats) != 1)
|
||||
{
|
||||
if ((ns1 & 1) == 0)
|
||||
{
|
||||
pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
|
||||
if ( !pc->U.Stats )
|
||||
goto RESTART_MODEL;
|
||||
}
|
||||
pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
|
||||
}
|
||||
else
|
||||
{
|
||||
p=(STATE*) SubAlloc.AllocUnits(1);
|
||||
if ( !p )
|
||||
goto RESTART_MODEL;
|
||||
*p=pc->OneState;
|
||||
pc->U.Stats=p;
|
||||
if (p->Freq < MAX_FREQ/4-1)
|
||||
p->Freq += p->Freq;
|
||||
else
|
||||
p->Freq = MAX_FREQ-4;
|
||||
pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
|
||||
}
|
||||
cf=2*fs.Freq*(pc->U.SummFreq+6);
|
||||
sf=s0+pc->U.SummFreq;
|
||||
if (cf < 6*sf)
|
||||
{
|
||||
cf=1+(cf > sf)+(cf >= 4*sf);
|
||||
pc->U.SummFreq += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
|
||||
pc->U.SummFreq += cf;
|
||||
}
|
||||
p=pc->U.Stats+ns1;
|
||||
p->Successor=Successor;
|
||||
p->Symbol = fs.Symbol;
|
||||
p->Freq = cf;
|
||||
pc->NumStats=++ns1;
|
||||
}
|
||||
MaxContext=MinContext=fs.Successor;
|
||||
return;
|
||||
RESTART_MODEL:
|
||||
RestartModelRare();
|
||||
EscCount=0;
|
||||
}
|
||||
|
||||
// Tabulated escapes for exponential symbol distribution
|
||||
static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
|
||||
|
||||
inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
|
||||
{
|
||||
STATE& rs=OneState;
|
||||
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||
ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
|
||||
Model->NS2BSIndx[Suffix->NumStats-1]+
|
||||
Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
|
||||
((Model->RunLength >> 26) & 0x20)];
|
||||
if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
|
||||
{
|
||||
Model->FoundState=&rs;
|
||||
rs.Freq += (rs.Freq < 128);
|
||||
Model->Coder.SubRange.LowCount=0;
|
||||
Model->Coder.SubRange.HighCount=bs;
|
||||
bs = (bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2)) & 0xFFFF;
|
||||
Model->PrevSuccess=1;
|
||||
Model->RunLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Model->Coder.SubRange.LowCount=bs;
|
||||
bs = (bs-GET_MEAN(bs,PERIOD_BITS,2)) & 0xFFFF;
|
||||
Model->Coder.SubRange.HighCount=BIN_SCALE;
|
||||
Model->InitEsc=ExpEscape[bs >> 10];
|
||||
Model->NumMasked=1;
|
||||
Model->CharMask[rs.Symbol]=Model->EscCount;
|
||||
Model->PrevSuccess=0;
|
||||
Model->FoundState=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
|
||||
{
|
||||
(Model->FoundState=p)->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
if (p[0].Freq > p[-1].Freq)
|
||||
{
|
||||
_PPMD_SWAP(p[0],p[-1]);
|
||||
Model->FoundState=--p;
|
||||
if (p->Freq > MAX_FREQ)
|
||||
rescale(Model);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
|
||||
{
|
||||
Model->Coder.SubRange.scale=U.SummFreq;
|
||||
STATE* p=U.Stats;
|
||||
int i, HiCnt;
|
||||
int count=Model->Coder.GetCurrentCount();
|
||||
if (count>=Model->Coder.SubRange.scale)
|
||||
return(false);
|
||||
if (count < (HiCnt=p->Freq))
|
||||
{
|
||||
Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
|
||||
Model->RunLength += Model->PrevSuccess;
|
||||
(Model->FoundState=p)->Freq=(HiCnt += 4);
|
||||
U.SummFreq += 4;
|
||||
if (HiCnt > MAX_FREQ)
|
||||
rescale(Model);
|
||||
Model->Coder.SubRange.LowCount=0;
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
if (Model->FoundState==NULL)
|
||||
return(false);
|
||||
Model->PrevSuccess=0;
|
||||
i=NumStats-1;
|
||||
while ((HiCnt += (++p)->Freq) <= count)
|
||||
if (--i == 0)
|
||||
{
|
||||
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||
Model->Coder.SubRange.LowCount=HiCnt;
|
||||
Model->CharMask[p->Symbol]=Model->EscCount;
|
||||
i=(Model->NumMasked=NumStats)-1;
|
||||
Model->FoundState=NULL;
|
||||
do
|
||||
{
|
||||
Model->CharMask[(--p)->Symbol]=Model->EscCount;
|
||||
} while ( --i );
|
||||
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||
return(true);
|
||||
}
|
||||
Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||
update1(Model,p);
|
||||
return(true);
|
||||
}
|
||||
|
||||
inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
|
||||
{
|
||||
(Model->FoundState=p)->Freq += 4;
|
||||
U.SummFreq += 4;
|
||||
if (p->Freq > MAX_FREQ)
|
||||
rescale(Model);
|
||||
Model->EscCount++;
|
||||
Model->RunLength=Model->InitRL;
|
||||
}
|
||||
|
||||
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
|
||||
{
|
||||
SEE2_CONTEXT* psee2c;
|
||||
if (NumStats != 256)
|
||||
{
|
||||
psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
|
||||
(Diff < Suffix->NumStats-NumStats)+
|
||||
2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
|
||||
Model->HiBitsFlag;
|
||||
Model->Coder.SubRange.scale=psee2c->getMean();
|
||||
}
|
||||
else
|
||||
{
|
||||
psee2c=&Model->DummySEE2Cont;
|
||||
Model->Coder.SubRange.scale=1;
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
|
||||
inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
|
||||
{
|
||||
int count, HiCnt, i=NumStats-Model->NumMasked;
|
||||
SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
|
||||
STATE* ps[256], ** pps=ps, * p=U.Stats-1;
|
||||
HiCnt=0;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
p++;
|
||||
} while (Model->CharMask[p->Symbol] == Model->EscCount);
|
||||
HiCnt += p->Freq;
|
||||
*pps++ = p;
|
||||
} while ( --i );
|
||||
Model->Coder.SubRange.scale += HiCnt;
|
||||
count=Model->Coder.GetCurrentCount();
|
||||
if (count>=Model->Coder.SubRange.scale)
|
||||
return(false);
|
||||
p=*(pps=ps);
|
||||
if (count < HiCnt)
|
||||
{
|
||||
HiCnt=0;
|
||||
while ((HiCnt += p->Freq) <= count)
|
||||
p=*++pps;
|
||||
Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||
psee2c->update();
|
||||
update2(Model,p);
|
||||
}
|
||||
else
|
||||
{
|
||||
Model->Coder.SubRange.LowCount=HiCnt;
|
||||
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||
i=NumStats-Model->NumMasked;
|
||||
pps--;
|
||||
do
|
||||
{
|
||||
Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
|
||||
} while ( --i );
|
||||
psee2c->Summ += Model->Coder.SubRange.scale;
|
||||
Model->NumMasked = NumStats;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
inline void ModelPPM::ClearMask()
|
||||
{
|
||||
EscCount=1;
|
||||
memset(CharMask,0,sizeof(CharMask));
|
||||
}
|
||||
|
||||
bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar )
|
||||
{
|
||||
int MaxOrder=UnpackRead->GetChar();
|
||||
bool Reset=MaxOrder & 0x20;
|
||||
|
||||
if (Reset)
|
||||
MaxMB = UnpackRead->GetChar() + 1;
|
||||
else
|
||||
if (SubAlloc.GetAllocatedMemory()==0)
|
||||
return(false);
|
||||
if (MaxOrder & 0x40)
|
||||
EscChar=UnpackRead->GetChar();
|
||||
Coder.InitDecoder(UnpackRead);
|
||||
if (Reset)
|
||||
{
|
||||
MaxOrder=(MaxOrder & 0x1f)+1;
|
||||
if (MaxOrder>16)
|
||||
MaxOrder=16+(MaxOrder-16)*3;
|
||||
if (MaxOrder==1)
|
||||
{
|
||||
SubAlloc.StopSubAllocator();
|
||||
return(false);
|
||||
}
|
||||
SubAlloc.StartSubAllocator(MaxMB);
|
||||
StartModelRare(MaxOrder);
|
||||
}
|
||||
return(MinContext!=NULL);
|
||||
}
|
||||
|
||||
int ModelPPM::DecodeChar()
|
||||
{
|
||||
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
if (MinContext->NumStats != 1)
|
||||
{
|
||||
if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
if (!MinContext->decodeSymbol1(this))
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
MinContext->decodeBinSymbol(this);
|
||||
Coder.Decode();
|
||||
while ( !FoundState )
|
||||
{
|
||||
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
do
|
||||
{
|
||||
OrderFall++;
|
||||
MinContext=MinContext->Suffix;
|
||||
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||
return(-1);
|
||||
} while (MinContext->NumStats == NumMasked);
|
||||
if (!MinContext->decodeSymbol2(this))
|
||||
return(-1);
|
||||
Coder.Decode();
|
||||
}
|
||||
int Symbol=FoundState->Symbol;
|
||||
if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
|
||||
MinContext=MaxContext=FoundState->Successor;
|
||||
else
|
||||
{
|
||||
UpdateModel();
|
||||
if (EscCount == 0)
|
||||
ClearMask();
|
||||
}
|
||||
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||
return(Symbol);
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_PPMMODEL_
|
||||
#define _RAR_PPMMODEL_
|
||||
|
||||
const int MAX_O=64; /* maximum allowed model order */
|
||||
|
||||
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
|
||||
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct _PACK_ATTR SEE2_CONTEXT
|
||||
{ // SEE-contexts for PPM-contexts with masked symbols
|
||||
ushort Summ;
|
||||
byte Shift, Count;
|
||||
void init(int InitVal)
|
||||
{
|
||||
Summ=InitVal << (Shift=PERIOD_BITS-4);
|
||||
Count=4;
|
||||
}
|
||||
uint getMean()
|
||||
{
|
||||
uint RetVal=(Summ & 0xFFFF) >> Shift;
|
||||
Summ -= RetVal;
|
||||
return RetVal+(RetVal == 0);
|
||||
}
|
||||
void update()
|
||||
{
|
||||
if (Shift < PERIOD_BITS && --Count == 0)
|
||||
{
|
||||
Summ += Summ;
|
||||
Count=3 << Shift++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ModelPPM;
|
||||
struct PPM_CONTEXT;
|
||||
|
||||
struct _PACK_ATTR STATE
|
||||
{
|
||||
byte Symbol;
|
||||
byte Freq;
|
||||
PPM_CONTEXT* Successor;
|
||||
};
|
||||
|
||||
struct _PACK_ATTR FreqData
|
||||
{
|
||||
ushort SummFreq;
|
||||
STATE* Stats;
|
||||
};
|
||||
|
||||
struct PPM_CONTEXT
|
||||
{
|
||||
ushort NumStats;
|
||||
union
|
||||
{
|
||||
FreqData U;
|
||||
STATE OneState;
|
||||
};
|
||||
|
||||
PPM_CONTEXT* Suffix;
|
||||
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
|
||||
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
|
||||
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
|
||||
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
|
||||
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
|
||||
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
|
||||
inline void update1(ModelPPM *Model,STATE* p); // CD suffix
|
||||
inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
|
||||
void rescale(ModelPPM *Model);
|
||||
inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
|
||||
inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#define Max( x, y ) ((x) < (y) ? (y) : (x))
|
||||
const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
|
||||
const uint FIXED_UNIT_SIZE=12;
|
||||
|
||||
/*
|
||||
inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
|
||||
NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
|
||||
inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
|
||||
*/
|
||||
|
||||
inline void _PPMD_SWAP( STATE& t1,STATE& t2) { STATE tmp=t1; t1=t2; t2=tmp; }
|
||||
|
||||
// 'Carryless rangecoder' by Dmitry Subbotin
|
||||
class RangeCoder {
|
||||
public:
|
||||
void InitDecoder(Unpack *UnpackRead);
|
||||
inline int GetCurrentCount();
|
||||
inline uint GetCurrentShiftCount(uint SHIFT);
|
||||
inline void Decode();
|
||||
inline void PutChar(unsigned int c);
|
||||
inline unsigned int GetChar();
|
||||
|
||||
uint low, code, range;
|
||||
struct SUBRANGE
|
||||
{
|
||||
uint LowCount, HighCount, scale;
|
||||
} SubRange;
|
||||
|
||||
Unpack *UnpackRead;
|
||||
};
|
||||
|
||||
class ModelPPM
|
||||
{
|
||||
private:
|
||||
friend struct PPM_CONTEXT;
|
||||
|
||||
SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
|
||||
|
||||
struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
|
||||
STATE* FoundState; // found next state transition
|
||||
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
|
||||
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
byte EscCount, PrevSuccess, HiBitsFlag;
|
||||
ushort BinSumm[128][64]; // binary SEE-contexts
|
||||
|
||||
RangeCoder Coder;
|
||||
SubAllocator SubAlloc;
|
||||
|
||||
void RestartModelRare();
|
||||
void StartModelRare(int MaxOrder);
|
||||
inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
|
||||
|
||||
inline void UpdateModel();
|
||||
inline void ClearMask();
|
||||
public:
|
||||
int MaxMB; // mega memory allocation size, for informational purposes only
|
||||
ModelPPM( Rar_Error_Handler* );
|
||||
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
|
||||
int DecodeChar();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef RAR_COMMON_HPP
|
||||
#define RAR_COMMON_HPP
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
const int NM = 1024; // max filename length
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define Min( x, y ) ((x) < (y) ? (x) : (y))
|
||||
|
||||
// 64-bit int support disabled, since this library isn't meant for huge 2GB+ archives
|
||||
typedef long Int64;
|
||||
#define int64to32(x) ((uint)(x))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define _PACK_ATTR __attribute__ ((packed))
|
||||
#else
|
||||
#define _PACK_ATTR
|
||||
#endif
|
||||
|
||||
// used as base class to override new and delete to not throw exceptions
|
||||
struct Rar_Allocator
|
||||
{
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
void* operator new ( size_t s ) throw () { return malloc( s ); }
|
||||
#else
|
||||
void* operator new ( size_t s ) { return malloc( s ); }
|
||||
#endif
|
||||
void operator delete ( void* p ) { free( p ); }
|
||||
};
|
||||
|
||||
class Rar_Extractor_Impl;
|
||||
typedef Rar_Extractor_Impl Rar_Error_Handler;
|
||||
void rar_out_of_memory( Rar_Error_Handler* );
|
||||
|
||||
// lots of order dependencies here
|
||||
class Unpack;
|
||||
#include "rarmisc.hpp"
|
||||
#include "array.hpp"
|
||||
#include "headers.hpp"
|
||||
#include "archive.hpp"
|
||||
#include "rarvm.hpp"
|
||||
#include "suballoc.hpp"
|
||||
#include "model.hpp"
|
||||
#include "unpack.hpp"
|
||||
#include "Rar_Extractor_Impl.h"
|
||||
|
||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
// CRC
|
||||
|
||||
static uint CRCTab [256];
|
||||
|
||||
void InitCRC()
|
||||
{
|
||||
if ( !CRCTab [1] )
|
||||
{
|
||||
for ( int i = 256; --i >= 0; )
|
||||
{
|
||||
unsigned c = i;
|
||||
for ( int n = 8; --n >= 0; )
|
||||
c = (c >> 1) ^ (0xEDB88320L & -(c & 1));
|
||||
CRCTab [i] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint CRC( uint crc, void const* in, uint count )
|
||||
{
|
||||
byte const* p = (byte const*) in;
|
||||
byte const* end = (byte const*) in + count;
|
||||
while ( p < end )
|
||||
crc = (crc >> 8) ^ CRCTab [(crc & 0xFF) ^ *p++];
|
||||
return crc;
|
||||
}
|
||||
|
||||
ushort OldCRC( ushort crc, void const* in, uint count )
|
||||
{
|
||||
byte const* p = (byte const*) in;
|
||||
byte const* end = p + count;
|
||||
while ( p < end )
|
||||
{
|
||||
crc += *p++;
|
||||
crc = (crc << 1) | (crc >> 15 & 1);
|
||||
}
|
||||
return crc & 0xFFFF;
|
||||
}
|
||||
|
||||
// BitInput
|
||||
|
||||
BitInput::BitInput( Rar_Error_Handler* eh )
|
||||
{
|
||||
error_handler = eh;
|
||||
InBuf = (byte*) malloc( MAX_SIZE );
|
||||
if ( !InBuf )
|
||||
rar_out_of_memory( error_handler );
|
||||
}
|
||||
|
||||
BitInput::~BitInput()
|
||||
{
|
||||
free( InBuf );
|
||||
}
|
||||
|
||||
void BitInput::faddbits(int Bits)
|
||||
{
|
||||
addbits( Bits );
|
||||
}
|
||||
|
||||
unsigned int BitInput::fgetbits()
|
||||
{
|
||||
return getbits();
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_RARMISC_
|
||||
#define _RAR_RARMISC_
|
||||
|
||||
void InitCRC();
|
||||
uint CRC( uint crc, void const* in, uint count );
|
||||
ushort OldCRC( ushort crc, void const* in, uint count );
|
||||
|
||||
class BitInput {
|
||||
public:
|
||||
enum { MAX_SIZE = 0x8000 };
|
||||
protected:
|
||||
int InAddr, InBit;
|
||||
Rar_Error_Handler* error_handler;
|
||||
public:
|
||||
BitInput( Rar_Error_Handler* eh );
|
||||
~BitInput();
|
||||
|
||||
byte* InBuf;
|
||||
|
||||
void InitBitInput()
|
||||
{
|
||||
InAddr = InBit = 0;
|
||||
}
|
||||
void addbits( int Bits )
|
||||
{
|
||||
Bits += InBit;
|
||||
InAddr += Bits >> 3;
|
||||
InBit = Bits & 7;
|
||||
}
|
||||
unsigned int getbits()
|
||||
{
|
||||
unsigned int BitField = (uint) InBuf [InAddr] << 16;
|
||||
BitField |= (uint) InBuf [InAddr + 1] << 8;
|
||||
BitField |= (uint) InBuf [InAddr + 2];
|
||||
BitField >>= (8 - InBit);
|
||||
return BitField & 0xFFFF;
|
||||
}
|
||||
void faddbits( int Bits );
|
||||
unsigned int fgetbits();
|
||||
};
|
||||
|
||||
#define MAXWINSIZE 0x400000
|
||||
#define MAXWINMASK (MAXWINSIZE-1)
|
||||
|
||||
#define LOW_DIST_REP_COUNT 16
|
||||
|
||||
#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
#define DC 60
|
||||
#define LDC 17
|
||||
#define RC 28
|
||||
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
|
||||
#define BC 20
|
||||
|
||||
#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
#define DC20 48
|
||||
#define RC20 28
|
||||
#define BC20 19
|
||||
#define MC20 257
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,116 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_VM_
|
||||
#define _RAR_VM_
|
||||
|
||||
#define VM_STANDARDFILTERS
|
||||
#define VM_OPTIMIZE
|
||||
|
||||
#define VM_MEMSIZE 0x40000
|
||||
#define VM_MEMMASK (VM_MEMSIZE-1)
|
||||
#define VM_GLOBALMEMADDR 0x3C000
|
||||
#define VM_GLOBALMEMSIZE 0x2000
|
||||
#define VM_FIXEDGLOBALSIZE 64
|
||||
|
||||
enum VM_Commands
|
||||
{
|
||||
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
|
||||
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
|
||||
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
|
||||
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
|
||||
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
|
||||
|
||||
#ifdef VM_OPTIMIZE
|
||||
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
|
||||
|
||||
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
|
||||
VM_NEGB, VM_NEGD,
|
||||
#endif
|
||||
|
||||
VM_STANDARD
|
||||
};
|
||||
|
||||
enum VM_StandardFilters {
|
||||
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
|
||||
VMSF_DELTA, VMSF_UPCASE
|
||||
};
|
||||
|
||||
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
|
||||
|
||||
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
|
||||
|
||||
struct VM_PreparedOperand
|
||||
{
|
||||
VM_OpType Type;
|
||||
uint Data;
|
||||
uint Base;
|
||||
uint *Addr;
|
||||
};
|
||||
|
||||
struct VM_PreparedCommand
|
||||
{
|
||||
VM_Commands OpCode;
|
||||
bool ByteMode;
|
||||
VM_PreparedOperand Op1,Op2;
|
||||
};
|
||||
|
||||
|
||||
struct VM_PreparedProgram
|
||||
{
|
||||
VM_PreparedProgram( Rar_Error_Handler* eh ) : Cmd( eh ), GlobalData( eh ), StaticData( eh )
|
||||
{
|
||||
AltCmd = NULL;
|
||||
}
|
||||
|
||||
Rar_Array<VM_PreparedCommand> Cmd;
|
||||
VM_PreparedCommand *AltCmd;
|
||||
int CmdCount;
|
||||
|
||||
Rar_Array<byte> GlobalData;
|
||||
Rar_Array<byte> StaticData;
|
||||
uint InitR[7];
|
||||
|
||||
byte *FilteredData;
|
||||
unsigned int FilteredDataSize;
|
||||
|
||||
};
|
||||
|
||||
class RarVM : private BitInput
|
||||
{
|
||||
private:
|
||||
inline uint GetValue(bool ByteMode,uint *Addr);
|
||||
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
|
||||
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
|
||||
void PrintState(uint IP);
|
||||
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
|
||||
#ifdef VM_OPTIMIZE
|
||||
void Optimize(VM_PreparedProgram *Prg);
|
||||
#endif
|
||||
bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize);
|
||||
#ifdef VM_STANDARDFILTERS
|
||||
VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize);
|
||||
void ExecuteStandardFilter(VM_StandardFilters FilterType);
|
||||
unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
|
||||
void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
|
||||
int BitCount);
|
||||
#endif
|
||||
|
||||
byte *Mem;
|
||||
uint R[8];
|
||||
uint Flags;
|
||||
Rar_Error_Handler* error_handler;
|
||||
public:
|
||||
RarVM( Rar_Error_Handler* );
|
||||
~RarVM();
|
||||
void Init();
|
||||
void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
|
||||
void Execute(VM_PreparedProgram *Prg);
|
||||
void SetValue(uint *Addr,uint Value);
|
||||
void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
|
||||
static uint ReadData(BitInput &Inp);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||
This library is based on UnRAR (unrarsrc-3.6.8.tar.gz) by Alexander L.
|
||||
Roshal. The original sources have been heavily modified, trimmed down,
|
||||
and purged of all OS-specific calls for file access and other
|
||||
unnecessary operations. Refer to unrar_license.txt for full licensing
|
||||
terms. The original unRAR source is available at http://www.rarlab.com/
|
||||
|
||||
It is important to provide 1 byte alignment for structures in model.hpp.
|
||||
Now it contains '#pragma pack(1)' directive, but your compiler may
|
||||
require something else. Though Unrar should work with other model.hpp
|
||||
alignments, its memory requirements may increase significantly.
|
||||
Alignment in other modules is not important.
|
||||
|
||||
Dmitry Shkarin wrote PPMII text compression. Dmitry Subbotin wrote the
|
||||
carryless rangecoder.
|
||||
|
||||
Unrar source may be used in any software to handle RAR archives without
|
||||
limitations free of charge, but cannot be used to re-create the RAR
|
||||
compression algorithm, which is proprietary. Distribution of modified
|
||||
Unrar source in separate form or as a part of other software is
|
||||
permitted, provided that it is clearly stated in the documentation and
|
||||
source comments that the code may not be used to develop a RAR (WinRAR)
|
||||
compatible archiver.
|
||||
--
|
||||
Shay Green <gblargg@gmail.com>
|
|
@ -1,158 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
/****************************************************************************
|
||||
* This file is part of PPMd project *
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2000 *
|
||||
* Contents: memory allocation routines *
|
||||
****************************************************************************/
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#include "suballoc_inl.h"
|
||||
|
||||
SubAllocator::SubAllocator( Rar_Error_Handler* eh )
|
||||
{
|
||||
error_handler = eh;
|
||||
Clean();
|
||||
}
|
||||
|
||||
void SubAllocator::Clean()
|
||||
{
|
||||
SubAllocatorSize=0;
|
||||
}
|
||||
|
||||
void SubAllocator::StopSubAllocator()
|
||||
{
|
||||
if ( SubAllocatorSize )
|
||||
{
|
||||
SubAllocatorSize=0;
|
||||
free( HeapStart );
|
||||
HeapStart = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool SubAllocator::StartSubAllocator(int SASize)
|
||||
{
|
||||
uint t=SASize << 20;
|
||||
if (SubAllocatorSize == t)
|
||||
return true;
|
||||
StopSubAllocator();
|
||||
uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+UNIT_SIZE;
|
||||
HeapStart = (byte*) malloc( AllocSize );
|
||||
if ( !HeapStart )
|
||||
rar_out_of_memory( error_handler );
|
||||
|
||||
HeapEnd=HeapStart+AllocSize-UNIT_SIZE;
|
||||
SubAllocatorSize=t;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SubAllocator::InitSubAllocator()
|
||||
{
|
||||
int i, k;
|
||||
memset(FreeList,0,sizeof(FreeList));
|
||||
pText=HeapStart;
|
||||
uint Size2=FIXED_UNIT_SIZE*(SubAllocatorSize/8/FIXED_UNIT_SIZE*7);
|
||||
uint RealSize2=Size2/FIXED_UNIT_SIZE*UNIT_SIZE;
|
||||
uint Size1=SubAllocatorSize-Size2;
|
||||
uint RealSize1=Size1/FIXED_UNIT_SIZE*UNIT_SIZE+Size1%FIXED_UNIT_SIZE;
|
||||
HiUnit=HeapStart+SubAllocatorSize;
|
||||
LoUnit=UnitsStart=HeapStart+RealSize1;
|
||||
FakeUnitsStart=HeapStart+Size1;
|
||||
HiUnit=LoUnit+RealSize2;
|
||||
for (i=0,k=1;i < N1 ;i++,k += 1)
|
||||
Indx2Units[i]=k;
|
||||
for (k++;i < N1+N2 ;i++,k += 2)
|
||||
Indx2Units[i]=k;
|
||||
for (k++;i < N1+N2+N3 ;i++,k += 3)
|
||||
Indx2Units[i]=k;
|
||||
for (k++;i < N1+N2+N3+N4;i++,k += 4)
|
||||
Indx2Units[i]=k;
|
||||
for (GlueCount=k=i=0;k < 128;k++)
|
||||
{
|
||||
i += (Indx2Units[i] < k+1);
|
||||
Units2Indx[k]=i;
|
||||
}
|
||||
}
|
||||
|
||||
void* SubAllocator::AllocUnitsRare(int indx)
|
||||
{
|
||||
if ( !GlueCount )
|
||||
{
|
||||
GlueCount = 255;
|
||||
GlueFreeBlocks();
|
||||
if ( FreeList[indx].next )
|
||||
return RemoveNode(indx);
|
||||
}
|
||||
int i=indx;
|
||||
do
|
||||
{
|
||||
if (++i == N_INDEXES)
|
||||
{
|
||||
GlueCount--;
|
||||
i=U2B(Indx2Units[indx]);
|
||||
int j=12*Indx2Units[indx];
|
||||
if (FakeUnitsStart-pText > j)
|
||||
{
|
||||
FakeUnitsStart-=j;
|
||||
UnitsStart -= i;
|
||||
return(UnitsStart);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
} while ( !FreeList[i].next );
|
||||
void* RetVal=RemoveNode(i);
|
||||
SplitBlock(RetVal,i,indx);
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
void* SubAllocator::AllocContext()
|
||||
{
|
||||
if (HiUnit != LoUnit)
|
||||
return (HiUnit -= UNIT_SIZE);
|
||||
if ( FreeList->next )
|
||||
return RemoveNode(0);
|
||||
return AllocUnitsRare(0);
|
||||
}
|
||||
|
||||
void* SubAllocator::ExpandUnits(void* OldPtr,int OldNU)
|
||||
{
|
||||
int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1];
|
||||
if (i0 == i1)
|
||||
return OldPtr;
|
||||
void* ptr=AllocUnits(OldNU+1);
|
||||
if ( ptr )
|
||||
{
|
||||
memcpy(ptr,OldPtr,U2B(OldNU));
|
||||
InsertNode(OldPtr,i0);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* SubAllocator::ShrinkUnits(void* OldPtr,int OldNU,int NewNU)
|
||||
{
|
||||
int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1];
|
||||
if (i0 == i1)
|
||||
return OldPtr;
|
||||
if ( FreeList[i1].next )
|
||||
{
|
||||
void* ptr=RemoveNode(i1);
|
||||
memcpy(ptr,OldPtr,U2B(NewNU));
|
||||
InsertNode(OldPtr,i0);
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitBlock(OldPtr,i0,i1);
|
||||
return OldPtr;
|
||||
}
|
||||
}
|
||||
|
||||
void SubAllocator::FreeUnits(void* ptr,int OldNU)
|
||||
{
|
||||
InsertNode(ptr,Units2Indx[OldNU-1]);
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
/****************************************************************************
|
||||
* This file is part of PPMd project *
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2000 *
|
||||
* Contents: interface to memory allocation routines *
|
||||
****************************************************************************/
|
||||
#ifndef _SUBALLOC_H_
|
||||
#define _SUBALLOC_H_
|
||||
|
||||
const int N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4;
|
||||
const int N_INDEXES=N1+N2+N3+N4;
|
||||
|
||||
#pragma pack(1)
|
||||
struct _PACK_ATTR RAR_MEM_BLK
|
||||
{
|
||||
ushort Stamp, NU;
|
||||
RAR_MEM_BLK* next, * prev;
|
||||
void insertAt(RAR_MEM_BLK* p)
|
||||
{
|
||||
next=(prev=p)->next;
|
||||
p->next=next->prev=this;
|
||||
}
|
||||
void remove()
|
||||
{
|
||||
prev->next=next;
|
||||
next->prev=prev;
|
||||
}
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
struct RAR_NODE
|
||||
{
|
||||
RAR_NODE* next;
|
||||
};
|
||||
|
||||
class SubAllocator
|
||||
{
|
||||
private:
|
||||
void InsertNode(void* p,int indx);
|
||||
void* RemoveNode(int indx);
|
||||
uint U2B(int NU);
|
||||
void SplitBlock(void* pv,int OldIndx,int NewIndx);
|
||||
uint GetUsedMemory();
|
||||
void GlueFreeBlocks();
|
||||
void* AllocUnitsRare(int indx);
|
||||
|
||||
long SubAllocatorSize;
|
||||
byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
|
||||
byte *HeapStart,*LoUnit, *HiUnit;
|
||||
struct RAR_NODE FreeList[N_INDEXES];
|
||||
Rar_Error_Handler* error_handler;
|
||||
public:
|
||||
SubAllocator( Rar_Error_Handler* );
|
||||
~SubAllocator() {StopSubAllocator();}
|
||||
void Clean();
|
||||
bool StartSubAllocator(int SASize);
|
||||
void StopSubAllocator();
|
||||
void InitSubAllocator();
|
||||
void* AllocContext();
|
||||
void* AllocUnits(int NU);
|
||||
void* ExpandUnits(void* ptr,int OldNU);
|
||||
void* ShrinkUnits(void* ptr,int OldNU,int NewNU);
|
||||
void FreeUnits(void* ptr,int OldNU);
|
||||
long GetAllocatedMemory() {return(SubAllocatorSize);};
|
||||
|
||||
byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
|
||||
};
|
||||
|
||||
#endif /* !defined(_SUBALLOC_H_) */
|
|
@ -1,88 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
/****************************************************************************
|
||||
* This file is part of PPMd project *
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2000 *
|
||||
* Contents: interface to memory allocation routines *
|
||||
****************************************************************************/
|
||||
|
||||
inline uint SubAllocator::U2B(int NU)
|
||||
{
|
||||
return /*8*NU+4*NU*/UNIT_SIZE*NU;
|
||||
}
|
||||
|
||||
inline void* SubAllocator::RemoveNode(int indx)
|
||||
{
|
||||
RAR_NODE* RetVal=FreeList[indx].next;
|
||||
FreeList[indx].next=RetVal->next;
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
inline void* SubAllocator::AllocUnits(int NU)
|
||||
{
|
||||
int indx=Units2Indx[NU-1];
|
||||
if ( FreeList[indx].next )
|
||||
return RemoveNode(indx);
|
||||
void* RetVal=LoUnit;
|
||||
LoUnit += U2B(Indx2Units[indx]);
|
||||
if (LoUnit <= HiUnit)
|
||||
return RetVal;
|
||||
LoUnit -= U2B(Indx2Units[indx]);
|
||||
return AllocUnitsRare(indx);
|
||||
}
|
||||
|
||||
inline void SubAllocator::InsertNode(void* p,int indx)
|
||||
{
|
||||
((RAR_NODE*) p)->next=FreeList[indx].next;
|
||||
FreeList[indx].next=(RAR_NODE*) p;
|
||||
}
|
||||
|
||||
inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx)
|
||||
{
|
||||
int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx];
|
||||
byte* p=((byte*) pv)+U2B(Indx2Units[NewIndx]);
|
||||
if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff)
|
||||
{
|
||||
InsertNode(p,--i);
|
||||
p += U2B(i=Indx2Units[i]);
|
||||
UDiff -= i;
|
||||
}
|
||||
InsertNode(p,Units2Indx[UDiff-1]);
|
||||
}
|
||||
|
||||
inline void SubAllocator::GlueFreeBlocks()
|
||||
{
|
||||
RAR_MEM_BLK s0, * p, * p1;
|
||||
int i, k, sz;
|
||||
if (LoUnit != HiUnit)
|
||||
*LoUnit=0;
|
||||
for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
|
||||
while ( FreeList[i].next )
|
||||
{
|
||||
p=(RAR_MEM_BLK*)RemoveNode(i);
|
||||
p->insertAt(&s0);
|
||||
p->Stamp=0xFFFF;
|
||||
p->NU=Indx2Units[i];
|
||||
}
|
||||
for (p=s0.next;p != &s0;p=p->next)
|
||||
while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000)
|
||||
{
|
||||
p1->remove();
|
||||
p->NU += p1->NU;
|
||||
}
|
||||
while ((p=s0.next) != &s0)
|
||||
{
|
||||
for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128)
|
||||
InsertNode(p,N_INDEXES-1);
|
||||
if (Indx2Units[i=Units2Indx[sz-1]] != sz)
|
||||
{
|
||||
k=sz-Indx2Units[--i];
|
||||
InsertNode(p+(sz-k),k-1);
|
||||
}
|
||||
InsertNode(p,i);
|
||||
}
|
||||
}
|
|
@ -1,918 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
|
||||
// higher level breaks code in CW4 (but not in CW9)
|
||||
#pragma optimization_level 1
|
||||
#endif
|
||||
|
||||
Unpack::Unpack( Rar_Extractor_Impl *DataIO, Rar_Error_Handler* eh ) :
|
||||
BitInput( eh ), VMCode( eh ), Inp( eh ), PPM( eh ), VM( eh ),
|
||||
Filters( eh ), PrgStack( eh ), OldFilterLengths( eh )
|
||||
{
|
||||
error_handler = eh;
|
||||
UnpIO=DataIO;
|
||||
Window=NULL;
|
||||
ExternalWindow=false;
|
||||
Suspended=false;
|
||||
UnpAllBuf=false;
|
||||
UnpSomeRead=false;
|
||||
}
|
||||
|
||||
Unpack::~Unpack()
|
||||
{
|
||||
if (Window!=NULL && !ExternalWindow)
|
||||
free( Window );
|
||||
InitFilters();
|
||||
}
|
||||
|
||||
void Unpack::Init(byte *Window)
|
||||
{
|
||||
if (Window==NULL)
|
||||
{
|
||||
Unpack::Window = (byte*) malloc( MAXWINSIZE );
|
||||
if ( !Unpack::Window )
|
||||
rar_out_of_memory( error_handler );
|
||||
}
|
||||
else
|
||||
{
|
||||
Unpack::Window=Window;
|
||||
ExternalWindow=true;
|
||||
}
|
||||
UnpInitData(false);
|
||||
}
|
||||
|
||||
void Unpack::DoUnpack(int Method,bool Solid)
|
||||
{
|
||||
switch(Method)
|
||||
{
|
||||
case 15: // rar 1.5 compression
|
||||
Unpack15(Solid);
|
||||
break;
|
||||
|
||||
case 20: // rar 2.x compression
|
||||
case 26: // files larger than 2GB
|
||||
Unpack20(Solid);
|
||||
break;
|
||||
|
||||
case 29: // rar 3.x compression
|
||||
Unpack29(Solid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Unpack::InsertOldDist(unsigned int Distance)
|
||||
{
|
||||
OldDist[3]=OldDist[2];
|
||||
OldDist[2]=OldDist[1];
|
||||
OldDist[1]=OldDist[0];
|
||||
OldDist[0]=Distance;
|
||||
}
|
||||
|
||||
inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance)
|
||||
{
|
||||
LastDist=Distance;
|
||||
LastLength=Length;
|
||||
}
|
||||
|
||||
void Unpack::CopyString(unsigned int Length,unsigned int Distance)
|
||||
{
|
||||
unsigned int DestPtr=UnpPtr-Distance;
|
||||
if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260)
|
||||
{
|
||||
Window[UnpPtr++]=Window[DestPtr++];
|
||||
while (--Length>0)
|
||||
Window[UnpPtr++]=Window[DestPtr++];
|
||||
}
|
||||
else
|
||||
while (Length--)
|
||||
{
|
||||
Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
|
||||
UnpPtr=(UnpPtr+1) & MAXWINMASK;
|
||||
}
|
||||
}
|
||||
|
||||
int Unpack::DecodeNumber(struct Decode *Dec)
|
||||
{
|
||||
unsigned int Bits;
|
||||
unsigned int BitField=getbits() & 0xfffe;
|
||||
if (BitField<Dec->DecodeLen[8])
|
||||
if (BitField<Dec->DecodeLen[4])
|
||||
if (BitField<Dec->DecodeLen[2])
|
||||
if (BitField<Dec->DecodeLen[1])
|
||||
Bits=1;
|
||||
else
|
||||
Bits=2;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[3])
|
||||
Bits=3;
|
||||
else
|
||||
Bits=4;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[6])
|
||||
if (BitField<Dec->DecodeLen[5])
|
||||
Bits=5;
|
||||
else
|
||||
Bits=6;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[7])
|
||||
Bits=7;
|
||||
else
|
||||
Bits=8;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[12])
|
||||
if (BitField<Dec->DecodeLen[10])
|
||||
if (BitField<Dec->DecodeLen[9])
|
||||
Bits=9;
|
||||
else
|
||||
Bits=10;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[11])
|
||||
Bits=11;
|
||||
else
|
||||
Bits=12;
|
||||
else
|
||||
if (BitField<Dec->DecodeLen[14])
|
||||
if (BitField<Dec->DecodeLen[13])
|
||||
Bits=13;
|
||||
else
|
||||
Bits=14;
|
||||
else
|
||||
Bits=15;
|
||||
|
||||
addbits(Bits);
|
||||
unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));
|
||||
if (N>=Dec->MaxNum)
|
||||
N=0;
|
||||
return(Dec->DecodeNum[N]);
|
||||
}
|
||||
|
||||
void Unpack::Unpack29(bool Solid)
|
||||
{
|
||||
static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
static int DDecode[DC];
|
||||
static byte DBits[DC];
|
||||
static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
|
||||
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
|
||||
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
|
||||
unsigned int Bits;
|
||||
|
||||
if (DDecode[1]==0)
|
||||
{
|
||||
int Dist=0,BitLength=0,Slot=0;
|
||||
for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
|
||||
for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
|
||||
{
|
||||
DDecode[Slot]=Dist;
|
||||
DBits[Slot]=BitLength;
|
||||
}
|
||||
}
|
||||
|
||||
FileExtracted=true;
|
||||
|
||||
if (!Suspended)
|
||||
{
|
||||
UnpInitData(Solid);
|
||||
if (!UnpReadBuf())
|
||||
return;
|
||||
if ((!Solid || !TablesRead) && !ReadTables())
|
||||
return;
|
||||
}
|
||||
|
||||
if (PPMError)
|
||||
return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
UnpPtr&=MAXWINMASK;
|
||||
|
||||
if (InAddr>ReadBorder)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
break;
|
||||
}
|
||||
if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
|
||||
{
|
||||
UnpWriteBuf();
|
||||
if (WrittenFileSize>DestUnpSize)
|
||||
return;
|
||||
if (Suspended)
|
||||
{
|
||||
FileExtracted=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (UnpBlockType==BLOCK_PPM)
|
||||
{
|
||||
int Ch=PPM.DecodeChar();
|
||||
if (Ch==-1)
|
||||
{
|
||||
PPMError=true;
|
||||
break;
|
||||
}
|
||||
if (Ch==PPMEscChar)
|
||||
{
|
||||
int NextCh=PPM.DecodeChar();
|
||||
if (NextCh==0)
|
||||
{
|
||||
if (!ReadTables())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (NextCh==2 || NextCh==-1)
|
||||
break;
|
||||
if (NextCh==3)
|
||||
{
|
||||
if (!ReadVMCodePPM())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (NextCh==4)
|
||||
{
|
||||
unsigned int Distance=0,Length = 0;
|
||||
bool Failed=false;
|
||||
for (int I=0;I<4 && !Failed;I++)
|
||||
{
|
||||
int Ch=PPM.DecodeChar();
|
||||
if (Ch==-1)
|
||||
Failed=true;
|
||||
else
|
||||
if (I==3)
|
||||
Length=(byte)Ch;
|
||||
else
|
||||
Distance=(Distance<<8)+(byte)Ch;
|
||||
}
|
||||
if (Failed)
|
||||
break;
|
||||
CopyString(Length+32,Distance+2);
|
||||
continue;
|
||||
}
|
||||
if (NextCh==5)
|
||||
{
|
||||
int Length=PPM.DecodeChar();
|
||||
if (Length==-1)
|
||||
break;
|
||||
CopyString(Length+4,1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Window[UnpPtr++]=Ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
int Number=DecodeNumber((struct Decode *)&LD);
|
||||
if (Number<256)
|
||||
{
|
||||
Window[UnpPtr++]=(byte)Number;
|
||||
continue;
|
||||
}
|
||||
if (Number>=271)
|
||||
{
|
||||
int Length=LDecode[Number-=271]+3;
|
||||
if ((Bits=LBits[Number])>0)
|
||||
{
|
||||
Length+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
int DistNumber=DecodeNumber((struct Decode *)&DD);
|
||||
unsigned int Distance=DDecode[DistNumber]+1;
|
||||
if ((Bits=DBits[DistNumber])>0)
|
||||
{
|
||||
if (DistNumber>9)
|
||||
{
|
||||
if (Bits>4)
|
||||
{
|
||||
Distance+=((getbits()>>(20-Bits))<<4);
|
||||
addbits(Bits-4);
|
||||
}
|
||||
if (LowDistRepCount>0)
|
||||
{
|
||||
LowDistRepCount--;
|
||||
Distance+=PrevLowDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
int LowDist=DecodeNumber((struct Decode *)&LDD);
|
||||
if (LowDist==16)
|
||||
{
|
||||
LowDistRepCount=LOW_DIST_REP_COUNT-1;
|
||||
Distance+=PrevLowDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
Distance+=LowDist;
|
||||
PrevLowDist=LowDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Distance+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
}
|
||||
|
||||
if (Distance>=0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x40000L)
|
||||
Length++;
|
||||
}
|
||||
|
||||
InsertOldDist(Distance);
|
||||
InsertLastMatch(Length,Distance);
|
||||
CopyString(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number==256)
|
||||
{
|
||||
if (!ReadEndOfBlock())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (Number==257)
|
||||
{
|
||||
if (!ReadVMCode())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (Number==258)
|
||||
{
|
||||
if (LastLength!=0)
|
||||
CopyString(LastLength,LastDist);
|
||||
continue;
|
||||
}
|
||||
if (Number<263)
|
||||
{
|
||||
int DistNum=Number-259;
|
||||
unsigned int Distance=OldDist[DistNum];
|
||||
for (int I=DistNum;I>0;I--)
|
||||
OldDist[I]=OldDist[I-1];
|
||||
OldDist[0]=Distance;
|
||||
|
||||
int LengthNumber=DecodeNumber((struct Decode *)&RD);
|
||||
int Length=LDecode[LengthNumber]+2;
|
||||
if ((Bits=LBits[LengthNumber])>0)
|
||||
{
|
||||
Length+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
InsertLastMatch(Length,Distance);
|
||||
CopyString(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number<272)
|
||||
{
|
||||
unsigned int Distance=SDDecode[Number-=263]+1;
|
||||
if ((Bits=SDBits[Number])>0)
|
||||
{
|
||||
Distance+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
InsertOldDist(Distance);
|
||||
InsertLastMatch(2,Distance);
|
||||
CopyString(2,Distance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
UnpWriteBuf();
|
||||
}
|
||||
|
||||
bool Unpack::ReadEndOfBlock()
|
||||
{
|
||||
unsigned int BitField=getbits();
|
||||
bool NewTable,NewFile=false;
|
||||
if (BitField & 0x8000)
|
||||
{
|
||||
NewTable=true;
|
||||
addbits(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewFile=true;
|
||||
NewTable=(BitField & 0x4000);
|
||||
addbits(2);
|
||||
}
|
||||
TablesRead=!NewTable;
|
||||
return !(NewFile || NewTable && !ReadTables());
|
||||
}
|
||||
|
||||
bool Unpack::ReadVMCode()
|
||||
{
|
||||
unsigned int FirstByte=getbits()>>8;
|
||||
addbits(8);
|
||||
int Length=(FirstByte & 7)+1;
|
||||
if (Length==7)
|
||||
{
|
||||
Length=(getbits()>>8)+7;
|
||||
addbits(8);
|
||||
}
|
||||
else
|
||||
if (Length==8)
|
||||
{
|
||||
Length=getbits();
|
||||
addbits(16);
|
||||
}
|
||||
VMCode.Alloc( Length );
|
||||
for (int I=0;I<Length;I++)
|
||||
{
|
||||
if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)
|
||||
return(false);
|
||||
VMCode[I]=getbits()>>8;
|
||||
addbits(8);
|
||||
}
|
||||
return(AddVMCode(FirstByte,&VMCode[0],Length));
|
||||
}
|
||||
|
||||
bool Unpack::ReadVMCodePPM()
|
||||
{
|
||||
unsigned int FirstByte=PPM.DecodeChar();
|
||||
if ((int)FirstByte==-1)
|
||||
return(false);
|
||||
int Length=(FirstByte & 7)+1;
|
||||
if (Length==7)
|
||||
{
|
||||
int B1=PPM.DecodeChar();
|
||||
if (B1==-1)
|
||||
return(false);
|
||||
Length=B1+7;
|
||||
}
|
||||
else
|
||||
if (Length==8)
|
||||
{
|
||||
int B1=PPM.DecodeChar();
|
||||
if (B1==-1)
|
||||
return(false);
|
||||
int B2=PPM.DecodeChar();
|
||||
if (B2==-1)
|
||||
return(false);
|
||||
Length=B1*256+B2;
|
||||
}
|
||||
VMCode.Alloc( Length );
|
||||
for (int I=0;I<Length;I++)
|
||||
{
|
||||
int Ch=PPM.DecodeChar();
|
||||
if (Ch==-1)
|
||||
return(false);
|
||||
VMCode[I]=Ch;
|
||||
}
|
||||
return(AddVMCode(FirstByte,&VMCode[0],Length));
|
||||
}
|
||||
|
||||
bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
{
|
||||
// TODO: auto clear object to free bit input on normal return?
|
||||
Inp.InitBitInput();
|
||||
memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
|
||||
VMCode.Reset();
|
||||
VM.Init();
|
||||
|
||||
uint FiltPos;
|
||||
if (FirstByte & 0x80)
|
||||
{
|
||||
FiltPos=RarVM::ReadData(Inp);
|
||||
if (FiltPos==0)
|
||||
InitFilters();
|
||||
else
|
||||
FiltPos--;
|
||||
}
|
||||
else
|
||||
FiltPos=LastFilter;
|
||||
if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
|
||||
return(false);
|
||||
LastFilter=FiltPos;
|
||||
bool NewFilter=(FiltPos==Filters.Size());
|
||||
|
||||
UnpackFilter *Filter;
|
||||
if (NewFilter)
|
||||
{
|
||||
Filters.Add(1);
|
||||
Filters[Filters.Size()-1]=Filter=new UnpackFilter( error_handler );
|
||||
if ( !Filter )
|
||||
rar_out_of_memory( error_handler );
|
||||
OldFilterLengths.Add(1);
|
||||
Filter->ExecCount=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Filter=Filters[FiltPos];
|
||||
Filter->ExecCount++;
|
||||
}
|
||||
|
||||
UnpackFilter *StackFilter=new UnpackFilter( error_handler );
|
||||
if ( !StackFilter )
|
||||
rar_out_of_memory( error_handler );
|
||||
|
||||
int EmptyCount=0;
|
||||
for (int I2=0;I2<PrgStack.Size();I2++)
|
||||
{
|
||||
PrgStack[I2-EmptyCount]=PrgStack[I2];
|
||||
if (PrgStack[I2]==NULL)
|
||||
EmptyCount++;
|
||||
if (EmptyCount>0)
|
||||
PrgStack[I2]=NULL;
|
||||
}
|
||||
if (EmptyCount==0)
|
||||
{
|
||||
PrgStack.Add(1);
|
||||
EmptyCount=1;
|
||||
}
|
||||
int StackPos=PrgStack.Size()-EmptyCount;
|
||||
// TODO: could leak StackFilter before this point
|
||||
PrgStack[StackPos]=StackFilter;
|
||||
StackFilter->ExecCount=Filter->ExecCount;
|
||||
|
||||
uint BlockStart=RarVM::ReadData(Inp);
|
||||
if (FirstByte & 0x40)
|
||||
BlockStart+=258;
|
||||
StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;
|
||||
if (FirstByte & 0x20)
|
||||
StackFilter->BlockLength=RarVM::ReadData(Inp);
|
||||
else
|
||||
StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
|
||||
StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;
|
||||
|
||||
// DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
|
||||
|
||||
OldFilterLengths[FiltPos]=StackFilter->BlockLength;
|
||||
|
||||
memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
|
||||
StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
|
||||
StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
|
||||
StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
|
||||
if (FirstByte & 0x10)
|
||||
{
|
||||
unsigned int InitMask=Inp.fgetbits()>>9;
|
||||
Inp.faddbits(7);
|
||||
for (int I=0;I<7;I++)
|
||||
if (InitMask & (1<<I))
|
||||
StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
|
||||
}
|
||||
if (NewFilter)
|
||||
{
|
||||
uint VMCodeSize=RarVM::ReadData(Inp);
|
||||
if (VMCodeSize>=0x10000 || VMCodeSize==0)
|
||||
return(false);
|
||||
VMCode.Alloc( VMCodeSize );
|
||||
for (int I=0;I<VMCodeSize;I++)
|
||||
{
|
||||
VMCode[I]=Inp.fgetbits()>>8;
|
||||
Inp.faddbits(8);
|
||||
}
|
||||
VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
|
||||
VMCode.Reset();
|
||||
}
|
||||
StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
|
||||
StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
|
||||
|
||||
int StaticDataSize=Filter->Prg.StaticData.Size();
|
||||
if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
|
||||
{
|
||||
StackFilter->Prg.StaticData.Add(StaticDataSize);
|
||||
memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
|
||||
}
|
||||
|
||||
if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)
|
||||
{
|
||||
StackFilter->Prg.GlobalData.Reset();
|
||||
StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
|
||||
}
|
||||
byte *GlobalData=&StackFilter->Prg.GlobalData[0];
|
||||
for (int I=0;I<7;I++)
|
||||
VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
|
||||
VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
|
||||
VM.SetValue((uint *)&GlobalData[0x20],0);
|
||||
VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
|
||||
memset(&GlobalData[0x30],0,16);
|
||||
|
||||
if (FirstByte & 8)
|
||||
{
|
||||
uint DataSize=RarVM::ReadData(Inp);
|
||||
if (DataSize>=0x10000)
|
||||
return(false);
|
||||
unsigned int CurSize=StackFilter->Prg.GlobalData.Size();
|
||||
if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
|
||||
StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
|
||||
byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
|
||||
for (int I=0;I<DataSize;I++)
|
||||
{
|
||||
GlobalData[I]=Inp.fgetbits()>>8;
|
||||
Inp.faddbits(8);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Unpack::UnpReadBuf()
|
||||
{
|
||||
int DataSize=ReadTop-InAddr;
|
||||
if (DataSize<0)
|
||||
return(false);
|
||||
if (InAddr>BitInput::MAX_SIZE/2)
|
||||
{
|
||||
if (DataSize>0)
|
||||
memmove(InBuf,InBuf+InAddr,DataSize);
|
||||
InAddr=0;
|
||||
ReadTop=DataSize;
|
||||
}
|
||||
else
|
||||
DataSize=ReadTop;
|
||||
int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
|
||||
if (ReadCode>0)
|
||||
ReadTop+=ReadCode;
|
||||
ReadBorder=ReadTop-30;
|
||||
return(ReadCode!=-1);
|
||||
}
|
||||
|
||||
void Unpack::UnpWriteBuf()
|
||||
{
|
||||
unsigned int WrittenBorder=WrPtr;
|
||||
unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
|
||||
for (int I=0;I<PrgStack.Size();I++)
|
||||
{
|
||||
UnpackFilter *flt=PrgStack[I];
|
||||
if (flt==NULL)
|
||||
continue;
|
||||
if (flt->NextWindow)
|
||||
{
|
||||
flt->NextWindow=false;
|
||||
continue;
|
||||
}
|
||||
unsigned int BlockStart=flt->BlockStart;
|
||||
unsigned int BlockLength=flt->BlockLength;
|
||||
if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)
|
||||
{
|
||||
if (WrittenBorder!=BlockStart)
|
||||
{
|
||||
UnpWriteArea(WrittenBorder,BlockStart);
|
||||
WrittenBorder=BlockStart;
|
||||
WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
|
||||
}
|
||||
if (BlockLength<=WriteSize)
|
||||
{
|
||||
unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;
|
||||
if (BlockStart<BlockEnd || BlockEnd==0)
|
||||
VM.SetMemory(0,Window+BlockStart,BlockLength);
|
||||
else
|
||||
{
|
||||
unsigned int FirstPartLength=MAXWINSIZE-BlockStart;
|
||||
VM.SetMemory(0,Window+BlockStart,FirstPartLength);
|
||||
VM.SetMemory(FirstPartLength,Window,BlockEnd);
|
||||
}
|
||||
VM_PreparedProgram *Prg=&flt->Prg;
|
||||
ExecuteCode(Prg);
|
||||
|
||||
byte *FilteredData=Prg->FilteredData;
|
||||
unsigned int FilteredDataSize=Prg->FilteredDataSize;
|
||||
|
||||
delete PrgStack[I];
|
||||
PrgStack[I]=NULL;
|
||||
while (I+1<PrgStack.Size())
|
||||
{
|
||||
UnpackFilter *NextFilter=PrgStack[I+1];
|
||||
if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
|
||||
NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
|
||||
break;
|
||||
VM.SetMemory(0,FilteredData,FilteredDataSize);
|
||||
VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;
|
||||
ExecuteCode(NextPrg);
|
||||
FilteredData=NextPrg->FilteredData;
|
||||
FilteredDataSize=NextPrg->FilteredDataSize;
|
||||
I++;
|
||||
delete PrgStack[I];
|
||||
PrgStack[I]=NULL;
|
||||
}
|
||||
UnpIO->UnpWrite(FilteredData,FilteredDataSize);
|
||||
UnpSomeRead=true;
|
||||
WrittenFileSize+=FilteredDataSize;
|
||||
WrittenBorder=BlockEnd;
|
||||
WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int J=I;J<PrgStack.Size();J++)
|
||||
{
|
||||
UnpackFilter *flt=PrgStack[J];
|
||||
if (flt!=NULL && flt->NextWindow)
|
||||
flt->NextWindow=false;
|
||||
}
|
||||
WrPtr=WrittenBorder;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnpWriteArea(WrittenBorder,UnpPtr);
|
||||
WrPtr=UnpPtr;
|
||||
}
|
||||
|
||||
void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
|
||||
{
|
||||
if (Prg->GlobalData.Size()>0)
|
||||
{
|
||||
Prg->InitR[6]=int64to32(WrittenFileSize);
|
||||
VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
|
||||
VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>31>>1));
|
||||
VM.Execute(Prg);
|
||||
}
|
||||
}
|
||||
|
||||
void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)
|
||||
{
|
||||
if (EndPtr!=StartPtr)
|
||||
UnpSomeRead=true;
|
||||
if (EndPtr<StartPtr)
|
||||
{
|
||||
UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK);
|
||||
UnpWriteData(Window,EndPtr);
|
||||
UnpAllBuf=true;
|
||||
}
|
||||
else
|
||||
UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);
|
||||
}
|
||||
|
||||
void Unpack::UnpWriteData(byte *Data,int Size)
|
||||
{
|
||||
if (WrittenFileSize>=DestUnpSize)
|
||||
return;
|
||||
int WriteSize=Size;
|
||||
Int64 LeftToWrite=DestUnpSize-WrittenFileSize;
|
||||
if (WriteSize>LeftToWrite)
|
||||
WriteSize=int64to32(LeftToWrite);
|
||||
UnpIO->UnpWrite(Data,WriteSize);
|
||||
WrittenFileSize+=Size;
|
||||
}
|
||||
|
||||
bool Unpack::ReadTables()
|
||||
{
|
||||
byte BitLength[BC];
|
||||
unsigned char Table[HUFF_TABLE_SIZE];
|
||||
if (InAddr>ReadTop-25)
|
||||
if (!UnpReadBuf())
|
||||
return(false);
|
||||
faddbits((8-InBit)&7);
|
||||
unsigned int BitField=fgetbits();
|
||||
if (BitField & 0x8000)
|
||||
{
|
||||
UnpBlockType=BLOCK_PPM;
|
||||
return(PPM.DecodeInit(this,PPMEscChar));
|
||||
}
|
||||
UnpBlockType=BLOCK_LZ;
|
||||
|
||||
PrevLowDist=0;
|
||||
LowDistRepCount=0;
|
||||
|
||||
if (!(BitField & 0x4000))
|
||||
memset(UnpOldTable,0,sizeof(UnpOldTable));
|
||||
faddbits(2);
|
||||
|
||||
for (int I2=0;I2<BC;I2++)
|
||||
{
|
||||
int Length=(byte)(fgetbits() >> 12);
|
||||
faddbits(4);
|
||||
if (Length==15)
|
||||
{
|
||||
int ZeroCount=(byte)(fgetbits() >> 12);
|
||||
faddbits(4);
|
||||
if (ZeroCount==0)
|
||||
BitLength[I2]=15;
|
||||
else
|
||||
{
|
||||
ZeroCount+=2;
|
||||
while (ZeroCount-- > 0 && I2<sizeof(BitLength)/sizeof(BitLength[0]))
|
||||
BitLength[I2++]=0;
|
||||
I2--;
|
||||
}
|
||||
}
|
||||
else
|
||||
BitLength[I2]=Length;
|
||||
}
|
||||
MakeDecodeTables(BitLength,(struct Decode *)&BD,BC);
|
||||
|
||||
const int TableSize=HUFF_TABLE_SIZE;
|
||||
for (int I=0;I<TableSize;)
|
||||
{
|
||||
if (InAddr>ReadTop-5)
|
||||
if (!UnpReadBuf())
|
||||
return(false);
|
||||
int Number=DecodeNumber((struct Decode *)&BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=(Number+UnpOldTable[I]) & 0xf;
|
||||
I++;
|
||||
}
|
||||
else
|
||||
if (Number<18)
|
||||
{
|
||||
int N;
|
||||
if (Number==16)
|
||||
{
|
||||
N=(fgetbits() >> 13)+3;
|
||||
faddbits(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
N=(fgetbits() >> 9)+11;
|
||||
faddbits(7);
|
||||
}
|
||||
while (N-- > 0 && I<TableSize)
|
||||
{
|
||||
Table[I]=Table[I-1];
|
||||
I++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int N;
|
||||
if (Number==18)
|
||||
{
|
||||
N=(fgetbits() >> 13)+3;
|
||||
faddbits(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
N=(fgetbits() >> 9)+11;
|
||||
faddbits(7);
|
||||
}
|
||||
while (N-- > 0 && I<TableSize)
|
||||
Table[I++]=0;
|
||||
}
|
||||
}
|
||||
TablesRead=true;
|
||||
if (InAddr>ReadTop)
|
||||
return(false);
|
||||
MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC);
|
||||
MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC);
|
||||
MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC);
|
||||
MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC);
|
||||
memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
|
||||
return(true);
|
||||
}
|
||||
|
||||
void Unpack::UnpInitData(int Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
TablesRead=false;
|
||||
memset(OldDist,0,sizeof(OldDist));
|
||||
OldDistPtr=0;
|
||||
LastDist=LastLength=0;
|
||||
// memset(Window,0,MAXWINSIZE);
|
||||
memset(UnpOldTable,0,sizeof(UnpOldTable));
|
||||
UnpPtr=WrPtr=0;
|
||||
PPMEscChar=2;
|
||||
|
||||
InitFilters();
|
||||
}
|
||||
InitBitInput();
|
||||
PPMError=false;
|
||||
WrittenFileSize=0;
|
||||
ReadTop=0;
|
||||
ReadBorder=0;
|
||||
UnpInitData20(Solid);
|
||||
}
|
||||
|
||||
void Unpack::InitFilters()
|
||||
{
|
||||
OldFilterLengths.Reset();
|
||||
LastFilter=0;
|
||||
|
||||
for (int I2=0;I2<Filters.Size();I2++)
|
||||
delete Filters[I2];
|
||||
Filters.Reset();
|
||||
for (int I=0;I<PrgStack.Size();I++)
|
||||
delete PrgStack[I];
|
||||
PrgStack.Reset();
|
||||
}
|
||||
|
||||
void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size)
|
||||
{
|
||||
int LenCount[16],TmpPos[16],I;
|
||||
long M,N;
|
||||
memset(LenCount,0,sizeof(LenCount));
|
||||
memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
|
||||
for (I=0;I<Size;I++)
|
||||
LenCount[LenTab[I] & 0xF]++;
|
||||
|
||||
LenCount[0]=0;
|
||||
for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++)
|
||||
{
|
||||
N=2*(N+LenCount[I]);
|
||||
M=N<<(15-I);
|
||||
if (M>0xFFFF)
|
||||
M=0xFFFF;
|
||||
Dec->DecodeLen[I]=(unsigned int)M;
|
||||
TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1];
|
||||
}
|
||||
|
||||
for (I=0;I<Size;I++)
|
||||
if (LenTab[I]!=0)
|
||||
Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I;
|
||||
Dec->MaxNum=Size;
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#ifndef _RAR_UNPACK_
|
||||
#define _RAR_UNPACK_
|
||||
|
||||
enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM};
|
||||
|
||||
struct Decode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[2];
|
||||
};
|
||||
|
||||
struct LitDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[NC];
|
||||
};
|
||||
|
||||
struct DistDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[DC];
|
||||
};
|
||||
|
||||
struct LowDistDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[LDC];
|
||||
};
|
||||
|
||||
struct RepDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[RC];
|
||||
};
|
||||
|
||||
struct BitDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[BC];
|
||||
};
|
||||
|
||||
struct UnpackFilter : Rar_Allocator
|
||||
{
|
||||
unsigned int BlockStart;
|
||||
unsigned int BlockLength;
|
||||
unsigned int ExecCount;
|
||||
bool NextWindow;
|
||||
VM_PreparedProgram Prg;
|
||||
|
||||
UnpackFilter( Rar_Error_Handler* eh ) : Prg( eh ) { }
|
||||
};
|
||||
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
struct MultDecode
|
||||
{
|
||||
unsigned int MaxNum;
|
||||
unsigned int DecodeLen[16];
|
||||
unsigned int DecodePos[16];
|
||||
unsigned int DecodeNum[MC20];
|
||||
};
|
||||
|
||||
struct AudioVariables
|
||||
{
|
||||
int K1,K2,K3,K4,K5;
|
||||
int D1,D2,D3,D4;
|
||||
int LastDelta;
|
||||
unsigned int Dif[11];
|
||||
unsigned int ByteCount;
|
||||
int LastChar;
|
||||
};
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
|
||||
|
||||
class Unpack : private BitInput {
|
||||
private:
|
||||
void Unpack29(bool Solid);
|
||||
bool UnpReadBuf();
|
||||
void UnpWriteBuf();
|
||||
void ExecuteCode(VM_PreparedProgram *Prg);
|
||||
void UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr);
|
||||
void UnpWriteData(byte *Data,int Size);
|
||||
bool ReadTables();
|
||||
void MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size);
|
||||
int DecodeNumber(struct Decode *Dec);
|
||||
void CopyString();
|
||||
inline void InsertOldDist(unsigned int Distance);
|
||||
inline void InsertLastMatch(unsigned int Length,unsigned int Distance);
|
||||
void UnpInitData(int Solid);
|
||||
void CopyString(unsigned int Length,unsigned int Distance);
|
||||
bool ReadEndOfBlock();
|
||||
bool ReadVMCode();
|
||||
bool ReadVMCodePPM();
|
||||
bool AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize);
|
||||
void InitFilters();
|
||||
|
||||
Rar_Array<byte> VMCode; // here to avoid leaks
|
||||
BitInput Inp; // here to avoid leaks
|
||||
|
||||
Rar_Extractor_Impl *UnpIO;
|
||||
public:
|
||||
ModelPPM PPM;
|
||||
private:
|
||||
int PPMEscChar;
|
||||
|
||||
RarVM VM;
|
||||
Rar_Array<UnpackFilter*> Filters;
|
||||
Rar_Array<UnpackFilter*> PrgStack;
|
||||
Rar_Array<int> OldFilterLengths;
|
||||
int LastFilter;
|
||||
|
||||
bool TablesRead;
|
||||
struct LitDecode LD;
|
||||
struct DistDecode DD;
|
||||
struct LowDistDecode LDD;
|
||||
struct RepDecode RD;
|
||||
struct BitDecode BD;
|
||||
|
||||
unsigned int OldDist[4],OldDistPtr;
|
||||
unsigned int LastDist,LastLength;
|
||||
|
||||
unsigned int UnpPtr,WrPtr;
|
||||
|
||||
int ReadTop;
|
||||
int ReadBorder;
|
||||
|
||||
unsigned char UnpOldTable[HUFF_TABLE_SIZE];
|
||||
|
||||
int UnpBlockType;
|
||||
|
||||
byte *Window;
|
||||
bool ExternalWindow;
|
||||
|
||||
|
||||
Int64 DestUnpSize;
|
||||
|
||||
bool Suspended;
|
||||
bool UnpAllBuf;
|
||||
bool UnpSomeRead;
|
||||
Int64 WrittenFileSize;
|
||||
bool FileExtracted;
|
||||
bool PPMError;
|
||||
|
||||
int PrevLowDist,LowDistRepCount;
|
||||
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
void Unpack15(bool Solid);
|
||||
void ShortLZ();
|
||||
void LongLZ();
|
||||
void HuffDecode();
|
||||
void GetFlagsBuf();
|
||||
void OldUnpInitData(int Solid);
|
||||
void InitHuff();
|
||||
void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace);
|
||||
void OldCopyString(unsigned int Distance,unsigned int Length);
|
||||
unsigned int DecodeNum(int Num,unsigned int StartPos,
|
||||
unsigned int *DecTab,unsigned int *PosTab);
|
||||
void OldUnpWriteBuf();
|
||||
|
||||
unsigned int ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
|
||||
unsigned int Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
|
||||
unsigned int NToPl[256],NToPlB[256],NToPlC[256];
|
||||
unsigned int FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
|
||||
int Buf60,NumHuf,StMode,LCount,FlagsCnt;
|
||||
unsigned int Nhfb,Nlzb,MaxDist3;
|
||||
/***************************** Unpack v 1.5 *********************************/
|
||||
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
void Unpack20(bool Solid);
|
||||
struct MultDecode MD[4];
|
||||
unsigned char UnpOldTable20[MC20*4];
|
||||
int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta;
|
||||
void CopyString20(unsigned int Length,unsigned int Distance);
|
||||
bool ReadTables20();
|
||||
void UnpInitData20(int Solid);
|
||||
void ReadLastTables();
|
||||
byte DecodeAudio(int Delta);
|
||||
struct AudioVariables AudV[4];
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
|
||||
Rar_Error_Handler* error_handler;
|
||||
public:
|
||||
Unpack(Rar_Extractor_Impl *DataIO, Rar_Error_Handler* );
|
||||
~Unpack();
|
||||
void Init(byte *Window=NULL);
|
||||
void DoUnpack(int Method,bool Solid);
|
||||
bool IsFileExtracted() {return(FileExtracted);}
|
||||
void SetDestSize(Int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
|
||||
void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;}
|
||||
|
||||
unsigned int GetChar()
|
||||
{
|
||||
if (InAddr>BitInput::MAX_SIZE-30)
|
||||
UnpReadBuf();
|
||||
return(InBuf[InAddr++]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,519 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
|
||||
// higher level breaks code in CW4 (but not in CW9)
|
||||
#pragma optimization_level 1
|
||||
#endif
|
||||
|
||||
#define STARTL1 2
|
||||
static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00,
|
||||
0xee00,0xf000,0xf200,0xf200,0xffff};
|
||||
static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32};
|
||||
|
||||
#define STARTL2 3
|
||||
static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00,
|
||||
0xf000,0xf200,0xf240,0xffff};
|
||||
static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36};
|
||||
|
||||
#define STARTHF0 4
|
||||
static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200,
|
||||
0xf200,0xf200,0xffff};
|
||||
static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33};
|
||||
|
||||
|
||||
#define STARTHF1 5
|
||||
static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200,
|
||||
0xf7e0,0xffff};
|
||||
static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127};
|
||||
|
||||
|
||||
#define STARTHF2 5
|
||||
static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff,
|
||||
0xffff,0xffff};
|
||||
static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0};
|
||||
|
||||
|
||||
#define STARTHF3 6
|
||||
static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff,
|
||||
0xffff};
|
||||
static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0};
|
||||
|
||||
|
||||
#define STARTHF4 8
|
||||
static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff};
|
||||
static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0};
|
||||
|
||||
|
||||
void Unpack::Unpack15(bool Solid)
|
||||
{
|
||||
if (Suspended)
|
||||
UnpPtr=WrPtr;
|
||||
else
|
||||
{
|
||||
UnpInitData(Solid);
|
||||
OldUnpInitData(Solid);
|
||||
UnpReadBuf();
|
||||
if (!Solid)
|
||||
{
|
||||
InitHuff();
|
||||
UnpPtr=0;
|
||||
}
|
||||
else
|
||||
UnpPtr=WrPtr;
|
||||
--DestUnpSize;
|
||||
}
|
||||
if (DestUnpSize>=0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt=8;
|
||||
}
|
||||
|
||||
while (DestUnpSize>=0)
|
||||
{
|
||||
UnpPtr&=MAXWINMASK;
|
||||
|
||||
if (InAddr>ReadTop-30 && !UnpReadBuf())
|
||||
break;
|
||||
if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
|
||||
{
|
||||
OldUnpWriteBuf();
|
||||
if (Suspended)
|
||||
return;
|
||||
}
|
||||
if (StMode)
|
||||
{
|
||||
HuffDecode();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (--FlagsCnt < 0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt=7;
|
||||
}
|
||||
|
||||
if (FlagBuf & 0x80)
|
||||
{
|
||||
FlagBuf<<=1;
|
||||
if (Nlzb > Nhfb)
|
||||
LongLZ();
|
||||
else
|
||||
HuffDecode();
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagBuf<<=1;
|
||||
if (--FlagsCnt < 0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt=7;
|
||||
}
|
||||
if (FlagBuf & 0x80)
|
||||
{
|
||||
FlagBuf<<=1;
|
||||
if (Nlzb > Nhfb)
|
||||
HuffDecode();
|
||||
else
|
||||
LongLZ();
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagBuf<<=1;
|
||||
ShortLZ();
|
||||
}
|
||||
}
|
||||
}
|
||||
OldUnpWriteBuf();
|
||||
}
|
||||
|
||||
|
||||
void Unpack::OldUnpWriteBuf()
|
||||
{
|
||||
if (UnpPtr!=WrPtr)
|
||||
UnpSomeRead=true;
|
||||
if (UnpPtr<WrPtr)
|
||||
{
|
||||
UnpIO->UnpWrite(&Window[WrPtr],-WrPtr & MAXWINMASK);
|
||||
UnpIO->UnpWrite(Window,UnpPtr);
|
||||
UnpAllBuf=true;
|
||||
}
|
||||
else
|
||||
UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr);
|
||||
WrPtr=UnpPtr;
|
||||
}
|
||||
|
||||
|
||||
void Unpack::ShortLZ()
|
||||
{
|
||||
static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
|
||||
static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,
|
||||
0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
|
||||
static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0};
|
||||
static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,
|
||||
0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
|
||||
|
||||
|
||||
unsigned int Length,SaveLength;
|
||||
unsigned int LastDistance;
|
||||
unsigned int Distance;
|
||||
int DistancePlace;
|
||||
NumHuf=0;
|
||||
|
||||
unsigned int BitField=fgetbits();
|
||||
if (LCount==2)
|
||||
{
|
||||
faddbits(1);
|
||||
if (BitField >= 0x8000)
|
||||
{
|
||||
OldCopyString((unsigned int)LastDist,LastLength);
|
||||
return;
|
||||
}
|
||||
BitField <<= 1;
|
||||
LCount=0;
|
||||
}
|
||||
|
||||
BitField>>=8;
|
||||
|
||||
ShortLen1[1]=ShortLen2[3]=Buf60+3;
|
||||
|
||||
if (AvrLn1<37)
|
||||
{
|
||||
for (Length=0;;Length++)
|
||||
if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0)
|
||||
break;
|
||||
faddbits(ShortLen1[Length]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Length=0;;Length++)
|
||||
if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0)
|
||||
break;
|
||||
faddbits(ShortLen2[Length]);
|
||||
}
|
||||
|
||||
if (Length >= 9)
|
||||
{
|
||||
if (Length == 9)
|
||||
{
|
||||
LCount++;
|
||||
OldCopyString((unsigned int)LastDist,LastLength);
|
||||
return;
|
||||
}
|
||||
if (Length == 14)
|
||||
{
|
||||
LCount=0;
|
||||
Length=DecodeNum(fgetbits(),STARTL2,DecL2,PosL2)+5;
|
||||
Distance=(fgetbits()>>1) | 0x8000;
|
||||
faddbits(15);
|
||||
LastLength=Length;
|
||||
LastDist=Distance;
|
||||
OldCopyString(Distance,Length);
|
||||
return;
|
||||
}
|
||||
|
||||
LCount=0;
|
||||
SaveLength=Length;
|
||||
Distance=OldDist[(OldDistPtr-(Length-9)) & 3];
|
||||
Length=DecodeNum(fgetbits(),STARTL1,DecL1,PosL1)+2;
|
||||
if (Length==0x101 && SaveLength==10)
|
||||
{
|
||||
Buf60 ^= 1;
|
||||
return;
|
||||
}
|
||||
if (Distance > 256)
|
||||
Length++;
|
||||
if (Distance >= MaxDist3)
|
||||
Length++;
|
||||
|
||||
OldDist[OldDistPtr++]=Distance;
|
||||
OldDistPtr = OldDistPtr & 3;
|
||||
LastLength=Length;
|
||||
LastDist=Distance;
|
||||
OldCopyString(Distance,Length);
|
||||
return;
|
||||
}
|
||||
|
||||
LCount=0;
|
||||
AvrLn1 += Length;
|
||||
AvrLn1 -= AvrLn1 >> 4;
|
||||
|
||||
DistancePlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff;
|
||||
Distance=ChSetA[DistancePlace];
|
||||
if (--DistancePlace != -1)
|
||||
{
|
||||
PlaceA[Distance]--;
|
||||
LastDistance=ChSetA[DistancePlace];
|
||||
PlaceA[LastDistance]++;
|
||||
ChSetA[DistancePlace+1]=LastDistance;
|
||||
ChSetA[DistancePlace]=Distance;
|
||||
}
|
||||
Length+=2;
|
||||
OldDist[OldDistPtr++] = ++Distance;
|
||||
OldDistPtr = OldDistPtr & 3;
|
||||
LastLength=Length;
|
||||
LastDist=Distance;
|
||||
OldCopyString(Distance,Length);
|
||||
}
|
||||
|
||||
|
||||
void Unpack::LongLZ()
|
||||
{
|
||||
unsigned int Length;
|
||||
unsigned int Distance;
|
||||
unsigned int DistancePlace,NewDistancePlace;
|
||||
unsigned int OldAvr2,OldAvr3;
|
||||
|
||||
NumHuf=0;
|
||||
Nlzb+=16;
|
||||
if (Nlzb > 0xff)
|
||||
{
|
||||
Nlzb=0x90;
|
||||
Nhfb >>= 1;
|
||||
}
|
||||
OldAvr2=AvrLn2;
|
||||
|
||||
unsigned int BitField=fgetbits();
|
||||
if (AvrLn2 >= 122)
|
||||
Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
|
||||
else
|
||||
if (AvrLn2 >= 64)
|
||||
Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
|
||||
else
|
||||
if (BitField < 0x100)
|
||||
{
|
||||
Length=BitField;
|
||||
faddbits(16);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Length=0;((BitField<<Length)&0x8000)==0;Length++)
|
||||
;
|
||||
faddbits(Length+1);
|
||||
}
|
||||
|
||||
AvrLn2 += Length;
|
||||
AvrLn2 -= AvrLn2 >> 5;
|
||||
|
||||
BitField=fgetbits();
|
||||
if (AvrPlcB > 0x28ff)
|
||||
DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
|
||||
else
|
||||
if (AvrPlcB > 0x6ff)
|
||||
DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
|
||||
else
|
||||
DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
|
||||
|
||||
AvrPlcB += DistancePlace;
|
||||
AvrPlcB -= AvrPlcB >> 8;
|
||||
while (1)
|
||||
{
|
||||
Distance = ChSetB[DistancePlace & 0xff];
|
||||
NewDistancePlace = NToPlB[Distance++ & 0xff]++;
|
||||
if (!(Distance & 0xff))
|
||||
CorrHuff(ChSetB,NToPlB);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ChSetB[DistancePlace]=ChSetB[NewDistancePlace];
|
||||
ChSetB[NewDistancePlace]=Distance;
|
||||
|
||||
Distance=((Distance & 0xff00) | (fgetbits() >> 8)) >> 1;
|
||||
faddbits(7);
|
||||
|
||||
OldAvr3=AvrLn3;
|
||||
if (Length!=1 && Length!=4)
|
||||
if (Length==0 && Distance <= MaxDist3)
|
||||
{
|
||||
AvrLn3++;
|
||||
AvrLn3 -= AvrLn3 >> 8;
|
||||
}
|
||||
else
|
||||
if (AvrLn3 > 0)
|
||||
AvrLn3--;
|
||||
Length+=3;
|
||||
if (Distance >= MaxDist3)
|
||||
Length++;
|
||||
if (Distance <= 256)
|
||||
Length+=8;
|
||||
if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
|
||||
MaxDist3=0x7f00;
|
||||
else
|
||||
MaxDist3=0x2001;
|
||||
OldDist[OldDistPtr++]=Distance;
|
||||
OldDistPtr = OldDistPtr & 3;
|
||||
LastLength=Length;
|
||||
LastDist=Distance;
|
||||
OldCopyString(Distance,Length);
|
||||
}
|
||||
|
||||
|
||||
void Unpack::HuffDecode()
|
||||
{
|
||||
unsigned int CurByte,NewBytePlace;
|
||||
unsigned int Length;
|
||||
unsigned int Distance;
|
||||
int BytePlace;
|
||||
|
||||
unsigned int BitField=fgetbits();
|
||||
|
||||
if (AvrPlc > 0x75ff)
|
||||
BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
|
||||
else
|
||||
if (AvrPlc > 0x5dff)
|
||||
BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
|
||||
else
|
||||
if (AvrPlc > 0x35ff)
|
||||
BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
|
||||
else
|
||||
if (AvrPlc > 0x0dff)
|
||||
BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
|
||||
else
|
||||
BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
|
||||
BytePlace&=0xff;
|
||||
if (StMode)
|
||||
{
|
||||
if (BytePlace==0 && BitField > 0xfff)
|
||||
BytePlace=0x100;
|
||||
if (--BytePlace==-1)
|
||||
{
|
||||
BitField=fgetbits();
|
||||
faddbits(1);
|
||||
if (BitField & 0x8000)
|
||||
{
|
||||
NumHuf=StMode=0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = (BitField & 0x4000) ? 4 : 3;
|
||||
faddbits(1);
|
||||
Distance=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
|
||||
Distance = (Distance << 5) | (fgetbits() >> 11);
|
||||
faddbits(5);
|
||||
OldCopyString(Distance,Length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (NumHuf++ >= 16 && FlagsCnt==0)
|
||||
StMode=1;
|
||||
AvrPlc += BytePlace;
|
||||
AvrPlc -= AvrPlc >> 8;
|
||||
Nhfb+=16;
|
||||
if (Nhfb > 0xff)
|
||||
{
|
||||
Nhfb=0x90;
|
||||
Nlzb >>= 1;
|
||||
}
|
||||
|
||||
Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8);
|
||||
--DestUnpSize;
|
||||
|
||||
while (1)
|
||||
{
|
||||
CurByte=ChSet[BytePlace];
|
||||
NewBytePlace=NToPl[CurByte++ & 0xff]++;
|
||||
if ((CurByte & 0xff) > 0xa1)
|
||||
CorrHuff(ChSet,NToPl);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ChSet[BytePlace]=ChSet[NewBytePlace];
|
||||
ChSet[NewBytePlace]=CurByte;
|
||||
}
|
||||
|
||||
|
||||
void Unpack::GetFlagsBuf()
|
||||
{
|
||||
unsigned int Flags,NewFlagsPlace;
|
||||
unsigned int FlagsPlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
|
||||
|
||||
while (1)
|
||||
{
|
||||
Flags=ChSetC[FlagsPlace];
|
||||
FlagBuf=Flags>>8;
|
||||
NewFlagsPlace=NToPlC[Flags++ & 0xff]++;
|
||||
if ((Flags & 0xff) != 0)
|
||||
break;
|
||||
CorrHuff(ChSetC,NToPlC);
|
||||
}
|
||||
|
||||
ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace];
|
||||
ChSetC[NewFlagsPlace]=Flags;
|
||||
}
|
||||
|
||||
|
||||
void Unpack::OldUnpInitData(int Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0;
|
||||
AvrPlc=0x3500;
|
||||
MaxDist3=0x2001;
|
||||
Nhfb=Nlzb=0x80;
|
||||
}
|
||||
FlagsCnt=0;
|
||||
FlagBuf=0;
|
||||
StMode=0;
|
||||
LCount=0;
|
||||
ReadTop=0;
|
||||
}
|
||||
|
||||
|
||||
void Unpack::InitHuff()
|
||||
{
|
||||
for (unsigned int I=0;I<256;I++)
|
||||
{
|
||||
Place[I]=PlaceA[I]=PlaceB[I]=I;
|
||||
PlaceC[I]=(~I+1) & 0xff;
|
||||
ChSet[I]=ChSetB[I]=I<<8;
|
||||
ChSetA[I]=I;
|
||||
ChSetC[I]=((~I+1) & 0xff)<<8;
|
||||
}
|
||||
memset(NToPl,0,sizeof(NToPl));
|
||||
memset(NToPlB,0,sizeof(NToPlB));
|
||||
memset(NToPlC,0,sizeof(NToPlC));
|
||||
CorrHuff(ChSetB,NToPlB);
|
||||
}
|
||||
|
||||
|
||||
void Unpack::CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace)
|
||||
{
|
||||
int I,J;
|
||||
for (I=7;I>=0;I--)
|
||||
for (J=0;J<32;J++,CharSet++)
|
||||
*CharSet=(*CharSet & ~0xff) | I;
|
||||
memset(NumToPlace,0,sizeof(NToPl));
|
||||
for (I=6;I>=0;I--)
|
||||
NumToPlace[I]=(7-I)*32;
|
||||
}
|
||||
|
||||
|
||||
void Unpack::OldCopyString(unsigned int Distance,unsigned int Length)
|
||||
{
|
||||
DestUnpSize-=Length;
|
||||
while (Length--)
|
||||
{
|
||||
Window[UnpPtr]=Window[(UnpPtr-Distance) & MAXWINMASK];
|
||||
UnpPtr=(UnpPtr+1) & MAXWINMASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int Unpack::DecodeNum(int Num,unsigned int StartPos,
|
||||
unsigned int *DecTab,unsigned int *PosTab)
|
||||
{
|
||||
int I;
|
||||
for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
|
||||
StartPos++;
|
||||
faddbits(StartPos);
|
||||
return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]);
|
||||
}
|
|
@ -1,378 +0,0 @@
|
|||
// File_Extractor 0.4.2
|
||||
// This source code is a heavily modified version based on the unrar package.
|
||||
// It may not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
// See unrar_license.txt for copyright and licensing.
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#if defined (__MWERKS__) && __MWERKS__ < 0x3200
|
||||
// higher level breaks code in CW4 (but not in CW9)
|
||||
#pragma optimization_level 1
|
||||
#endif
|
||||
|
||||
void Unpack::CopyString20(unsigned int Length,unsigned int Distance)
|
||||
{
|
||||
LastDist=OldDist[OldDistPtr++ & 3]=Distance;
|
||||
LastLength=Length;
|
||||
DestUnpSize-=Length;
|
||||
|
||||
unsigned int DestPtr=UnpPtr-Distance;
|
||||
if (DestPtr<MAXWINSIZE-300 && UnpPtr<MAXWINSIZE-300)
|
||||
{
|
||||
Window[UnpPtr++]=Window[DestPtr++];
|
||||
Window[UnpPtr++]=Window[DestPtr++];
|
||||
while (Length>2)
|
||||
{
|
||||
Length--;
|
||||
Window[UnpPtr++]=Window[DestPtr++];
|
||||
}
|
||||
}
|
||||
else
|
||||
while (Length--)
|
||||
{
|
||||
Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
|
||||
UnpPtr=(UnpPtr+1) & MAXWINMASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Unpack::Unpack20(bool Solid)
|
||||
{
|
||||
static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
|
||||
static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
|
||||
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
|
||||
unsigned int Bits;
|
||||
|
||||
if (Suspended)
|
||||
UnpPtr=WrPtr;
|
||||
else
|
||||
{
|
||||
UnpInitData(Solid);
|
||||
if (!UnpReadBuf())
|
||||
return;
|
||||
if (!Solid)
|
||||
if (!ReadTables20())
|
||||
return;
|
||||
--DestUnpSize;
|
||||
}
|
||||
|
||||
while ( DestUnpSize >= 0 )
|
||||
{
|
||||
UnpPtr&=MAXWINMASK;
|
||||
|
||||
if (InAddr>ReadTop-30)
|
||||
if (!UnpReadBuf())
|
||||
break;
|
||||
if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
|
||||
{
|
||||
OldUnpWriteBuf();
|
||||
if (Suspended)
|
||||
return;
|
||||
}
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
int AudioNumber=DecodeNumber((struct Decode *)&MD[UnpCurChannel]);
|
||||
|
||||
if (AudioNumber==256)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
Window[UnpPtr++]=DecodeAudio(AudioNumber);
|
||||
if (++UnpCurChannel==UnpChannels)
|
||||
UnpCurChannel=0;
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
int Number=DecodeNumber((struct Decode *)&LD);
|
||||
if (Number<256)
|
||||
{
|
||||
Window[UnpPtr++]=(byte)Number;
|
||||
--DestUnpSize;
|
||||
continue;
|
||||
}
|
||||
if (Number>269)
|
||||
{
|
||||
int Length=LDecode[Number-=270]+3;
|
||||
if ((Bits=LBits[Number])>0)
|
||||
{
|
||||
Length+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
int DistNumber=DecodeNumber((struct Decode *)&DD);
|
||||
unsigned int Distance=DDecode[DistNumber]+1;
|
||||
if ((Bits=DBits[DistNumber])>0)
|
||||
{
|
||||
Distance+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
|
||||
if (Distance>=0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x40000L)
|
||||
Length++;
|
||||
}
|
||||
|
||||
CopyString20(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number==269)
|
||||
{
|
||||
if (!ReadTables20())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (Number==256)
|
||||
{
|
||||
CopyString20(LastLength,LastDist);
|
||||
continue;
|
||||
}
|
||||
if (Number<261)
|
||||
{
|
||||
unsigned int Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
|
||||
int LengthNumber=DecodeNumber((struct Decode *)&RD);
|
||||
int Length=LDecode[LengthNumber]+2;
|
||||
if ((Bits=LBits[LengthNumber])>0)
|
||||
{
|
||||
Length+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
if (Distance>=0x101)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x2000)
|
||||
{
|
||||
Length++;
|
||||
if (Distance>=0x40000)
|
||||
Length++;
|
||||
}
|
||||
}
|
||||
CopyString20(Length,Distance);
|
||||
continue;
|
||||
}
|
||||
if (Number<270)
|
||||
{
|
||||
unsigned int Distance=SDDecode[Number-=261]+1;
|
||||
if ((Bits=SDBits[Number])>0)
|
||||
{
|
||||
Distance+=getbits()>>(16-Bits);
|
||||
addbits(Bits);
|
||||
}
|
||||
CopyString20(2,Distance);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ReadLastTables();
|
||||
OldUnpWriteBuf();
|
||||
}
|
||||
|
||||
|
||||
bool Unpack::ReadTables20()
|
||||
{
|
||||
byte BitLength[BC20];
|
||||
unsigned char Table[MC20*4];
|
||||
int TableSize,N,I;
|
||||
if (InAddr>ReadTop-25)
|
||||
if (!UnpReadBuf())
|
||||
return(false);
|
||||
unsigned int BitField=getbits();
|
||||
UnpAudioBlock=(BitField & 0x8000);
|
||||
|
||||
if (!(BitField & 0x4000))
|
||||
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
|
||||
addbits(2);
|
||||
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
UnpChannels=((BitField>>12) & 3)+1;
|
||||
if (UnpCurChannel>=UnpChannels)
|
||||
UnpCurChannel=0;
|
||||
addbits(2);
|
||||
TableSize=MC20*UnpChannels;
|
||||
}
|
||||
else
|
||||
TableSize=NC20+DC20+RC20;
|
||||
|
||||
for (I=0;I<BC20;I++)
|
||||
{
|
||||
BitLength[I]=(byte)(getbits() >> 12);
|
||||
addbits(4);
|
||||
}
|
||||
MakeDecodeTables(BitLength,(struct Decode *)&BD,BC20);
|
||||
I=0;
|
||||
while (I<TableSize)
|
||||
{
|
||||
if (InAddr>ReadTop-5)
|
||||
if (!UnpReadBuf())
|
||||
return(false);
|
||||
int Number=DecodeNumber((struct Decode *)&BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=(Number+UnpOldTable20[I]) & 0xf;
|
||||
I++;
|
||||
}
|
||||
else
|
||||
if (Number==16)
|
||||
{
|
||||
N=(getbits() >> 14)+3;
|
||||
addbits(2);
|
||||
while (N-- > 0 && I<TableSize)
|
||||
{
|
||||
Table[I]=Table[I-1];
|
||||
I++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Number==17)
|
||||
{
|
||||
N=(getbits() >> 13)+3;
|
||||
addbits(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
N=(getbits() >> 9)+11;
|
||||
addbits(7);
|
||||
}
|
||||
while (N-- > 0 && I<TableSize)
|
||||
Table[I++]=0;
|
||||
}
|
||||
}
|
||||
if (InAddr>ReadTop)
|
||||
return(true);
|
||||
if (UnpAudioBlock)
|
||||
for (I=0;I<UnpChannels;I++)
|
||||
MakeDecodeTables(&Table[I*MC20],(struct Decode *)&MD[I],MC20);
|
||||
else
|
||||
{
|
||||
MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC20);
|
||||
MakeDecodeTables(&Table[NC20],(struct Decode *)&DD,DC20);
|
||||
MakeDecodeTables(&Table[NC20+DC20],(struct Decode *)&RD,RC20);
|
||||
}
|
||||
memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
void Unpack::ReadLastTables()
|
||||
{
|
||||
if (ReadTop>=InAddr+5)
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
if (DecodeNumber((struct Decode *)&MD[UnpCurChannel])==256)
|
||||
ReadTables20();
|
||||
}
|
||||
else
|
||||
if (DecodeNumber((struct Decode *)&LD)==269)
|
||||
ReadTables20();
|
||||
}
|
||||
|
||||
|
||||
void Unpack::UnpInitData20(int Solid)
|
||||
{
|
||||
if (!Solid)
|
||||
{
|
||||
UnpChannelDelta=UnpCurChannel=0;
|
||||
UnpChannels=1;
|
||||
memset(AudV,0,sizeof(AudV));
|
||||
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
byte Unpack::DecodeAudio(int Delta)
|
||||
{
|
||||
struct AudioVariables *V=&AudV[UnpCurChannel];
|
||||
V->ByteCount++;
|
||||
V->D4=V->D3;
|
||||
V->D3=V->D2;
|
||||
V->D2=V->LastDelta-V->D1;
|
||||
V->D1=V->LastDelta;
|
||||
int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
|
||||
PCh=(PCh>>3) & 0xFF;
|
||||
|
||||
unsigned int Ch=PCh-Delta;
|
||||
|
||||
int D=((signed char)Delta)<<3;
|
||||
|
||||
V->Dif[0]+=abs(D);
|
||||
V->Dif[1]+=abs(D-V->D1);
|
||||
V->Dif[2]+=abs(D+V->D1);
|
||||
V->Dif[3]+=abs(D-V->D2);
|
||||
V->Dif[4]+=abs(D+V->D2);
|
||||
V->Dif[5]+=abs(D-V->D3);
|
||||
V->Dif[6]+=abs(D+V->D3);
|
||||
V->Dif[7]+=abs(D-V->D4);
|
||||
V->Dif[8]+=abs(D+V->D4);
|
||||
V->Dif[9]+=abs(D-UnpChannelDelta);
|
||||
V->Dif[10]+=abs(D+UnpChannelDelta);
|
||||
|
||||
UnpChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar);
|
||||
V->LastChar=Ch;
|
||||
|
||||
if ((V->ByteCount & 0x1F)==0)
|
||||
{
|
||||
unsigned int MinDif=V->Dif[0],NumMinDif=0;
|
||||
V->Dif[0]=0;
|
||||
for (int I=1;I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++)
|
||||
{
|
||||
if (V->Dif[I]<MinDif)
|
||||
{
|
||||
MinDif=V->Dif[I];
|
||||
NumMinDif=I;
|
||||
}
|
||||
V->Dif[I]=0;
|
||||
}
|
||||
switch(NumMinDif)
|
||||
{
|
||||
case 1:
|
||||
if (V->K1>=-16)
|
||||
V->K1--;
|
||||
break;
|
||||
case 2:
|
||||
if (V->K1<16)
|
||||
V->K1++;
|
||||
break;
|
||||
case 3:
|
||||
if (V->K2>=-16)
|
||||
V->K2--;
|
||||
break;
|
||||
case 4:
|
||||
if (V->K2<16)
|
||||
V->K2++;
|
||||
break;
|
||||
case 5:
|
||||
if (V->K3>=-16)
|
||||
V->K3--;
|
||||
break;
|
||||
case 6:
|
||||
if (V->K3<16)
|
||||
V->K3++;
|
||||
break;
|
||||
case 7:
|
||||
if (V->K4>=-16)
|
||||
V->K4--;
|
||||
break;
|
||||
case 8:
|
||||
if (V->K4<16)
|
||||
V->K4++;
|
||||
break;
|
||||
case 9:
|
||||
if (V->K5>=-16)
|
||||
V->K5--;
|
||||
break;
|
||||
case 10:
|
||||
if (V->K5<16)
|
||||
V->K5++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return((byte)Ch);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
****** ***** ****** unRAR - free utility for RAR archives
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
****** ******* ****** License for use and distribution of
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
** ** ** ** ** ** FREE portable version
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The source code of unRAR utility is freeware. This means:
|
||||
|
||||
1. All copyrights to RAR and the utility unRAR are exclusively
|
||||
owned by the author - Alexander Roshal.
|
||||
|
||||
2. The unRAR sources may be used in any software to handle RAR
|
||||
archives without limitations free of charge, but cannot be used
|
||||
to re-create the RAR compression algorithm, which is proprietary.
|
||||
Distribution of modified unRAR sources in separate form or as a
|
||||
part of other software is permitted, provided that it is clearly
|
||||
stated in the documentation and source comments that the code may
|
||||
not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
|
||||
3. The unRAR utility may be freely distributed. No person or company
|
||||
may charge a fee for the distribution of unRAR without written
|
||||
permission from the copyright holder.
|
||||
|
||||
4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS".
|
||||
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
|
||||
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
|
||||
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
|
||||
OR MISUSING THIS SOFTWARE.
|
||||
|
||||
5. Installing and using the unRAR utility signifies acceptance of
|
||||
these terms and conditions of the license.
|
||||
|
||||
6. If you don't agree with terms of the license you must remove
|
||||
unRAR files from your storage devices and cease to use the
|
||||
utility.
|
||||
|
||||
Thank you for your interest in RAR and unRAR.
|
||||
|
||||
|
||||
Alexander L. Roshal
|
|
@ -27,7 +27,6 @@ extern "C" {
|
|||
|
||||
#ifdef HAS_FILE_EXTRACTOR
|
||||
#include <Zip_Extractor.h>
|
||||
#include <Rar_Extractor.h>
|
||||
#include <Zip7_Extractor.h>
|
||||
#endif
|
||||
|
||||
|
@ -544,19 +543,6 @@ bool utilIsZipFile(const char *file)
|
|||
}
|
||||
|
||||
#ifdef HAS_FILE_EXTRACTOR
|
||||
bool utilIsRarFile(const char *file)
|
||||
{
|
||||
if(strlen(file) > 4) {
|
||||
const char * p = strrchr(file,'.');
|
||||
|
||||
if(p != NULL) {
|
||||
if(_stricmp(p, ".rar") == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool utilIs7ZipFile(const char *file)
|
||||
{
|
||||
|
@ -608,8 +594,7 @@ IMAGE_TYPE utilFindType(const char *file)
|
|||
#ifdef HAS_FILE_EXTRACTOR
|
||||
int type = -1;
|
||||
if (utilIsZipFile(file)) type = 0;
|
||||
else if (utilIsRarFile(file)) type = 1;
|
||||
else if (utilIs7ZipFile(file)) type = 2;
|
||||
else if (utilIs7ZipFile(file)) type = 1;
|
||||
|
||||
if(type >= 0) {
|
||||
|
||||
|
@ -618,8 +603,7 @@ IMAGE_TYPE utilFindType(const char *file)
|
|||
|
||||
switch (type) {
|
||||
case 0: ex = new Zip_Extractor; break;
|
||||
case 1: ex = new Rar_Extractor; break;
|
||||
case 2: ex = new Zip7_Extractor; break;
|
||||
case 1: ex = new Zip7_Extractor; break;
|
||||
default: type = -1; break;
|
||||
}
|
||||
|
||||
|
@ -763,8 +747,7 @@ static u8 *utilLoadFromFE(const char *file,
|
|||
|
||||
switch (type) {
|
||||
case 0: ex = new Zip_Extractor; break;
|
||||
case 1: ex = new Rar_Extractor; break;
|
||||
case 2: ex = new Zip7_Extractor; break;
|
||||
case 1: ex = new Zip7_Extractor; break;
|
||||
default: type = -1; break;
|
||||
}
|
||||
|
||||
|
@ -1007,8 +990,7 @@ u8 *utilLoad(const char *file,
|
|||
#ifdef HAS_FILE_EXTRACTOR
|
||||
int type = -1;
|
||||
if (utilIsZipFile(file)) type = 0;
|
||||
else if (utilIsRarFile(file)) type = 1;
|
||||
else if (utilIs7ZipFile(file)) type = 2;
|
||||
else if (utilIs7ZipFile(file)) type = 1;
|
||||
|
||||
if(type>=0) {
|
||||
return utilLoadFromFE(file, type, accept, data, size);
|
||||
|
@ -1020,11 +1002,6 @@ u8 *utilLoad(const char *file,
|
|||
if(utilIsGzipFile(file)) {
|
||||
return utilLoadGzipFile(file, accept, data, size);
|
||||
}
|
||||
#if 0
|
||||
if(utilIsRarFile(file)) {
|
||||
return utilLoadRarFile(file, accept, data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
u8 *image = data;
|
||||
|
||||
|
|
Loading…
Reference in New Issue