JMA Support.
This commit is contained in:
26
zsnes/src/jma/7z.h
Normal file
26
zsnes/src/jma/7z.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __7Z_H
|
||||
#define __7Z_H
|
||||
|
||||
bool decompress_lzma_7z(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size) throw ();
|
||||
|
||||
#endif
|
||||
|
||||
46
zsnes/src/jma/7zlzma.cpp
Normal file
46
zsnes/src/jma/7zlzma.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "7z.h"
|
||||
|
||||
#include "lzmadec.h"
|
||||
|
||||
bool decompress_lzma_7z(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size) throw () {
|
||||
try {
|
||||
NCompress::NLZMA::CDecoder cc;
|
||||
|
||||
ISequentialInStream in(reinterpret_cast<const char*>(in_data), in_size);
|
||||
ISequentialOutStream out(reinterpret_cast<char*>(out_data), out_size);
|
||||
|
||||
UINT64 in_size_l = in_size;
|
||||
UINT64 out_size_l = out_size;
|
||||
|
||||
if (cc.ReadCoderProperties(&in) != S_OK)
|
||||
return false;
|
||||
|
||||
if (cc.Code(&in, &out, &in_size_l, &out_size_l) != S_OK)
|
||||
return false;
|
||||
|
||||
if (out.size_get() != out_size || out.overflow_get())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
40
zsnes/src/jma/aribitcd.cpp
Normal file
40
zsnes/src/jma/aribitcd.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "aribitcd.h"
|
||||
#include "ariprice.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace NCompression {
|
||||
namespace NArithmetic {
|
||||
|
||||
static const double kDummyMultMid = (1.0 / kBitPrice) / 2;
|
||||
|
||||
CPriceTables::CPriceTables()
|
||||
{
|
||||
double aLn2 = log(2);
|
||||
double aLnAll = log(kBitModelTotal >> kNumMoveReducingBits);
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
m_StatePrices[i] = UINT32((fabs(aLnAll - log(i)) / aLn2 + kDummyMultMid) * kBitPrice);
|
||||
}
|
||||
|
||||
CPriceTables g_PriceTables;
|
||||
|
||||
}}
|
||||
101
zsnes/src/jma/aribitcd.h
Normal file
101
zsnes/src/jma/aribitcd.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef __COMPRESSION_BITCODER_H
|
||||
#define __COMPRESSION_BITCODER_H
|
||||
|
||||
#include "rngcoder.h"
|
||||
|
||||
namespace NCompression {
|
||||
namespace NArithmetic {
|
||||
|
||||
const int kNumBitModelTotalBits = 11;
|
||||
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
|
||||
const int kNumMoveReducingBits = 2;
|
||||
|
||||
|
||||
class CPriceTables
|
||||
{
|
||||
public:
|
||||
UINT32 m_StatePrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
CPriceTables();
|
||||
};
|
||||
|
||||
extern CPriceTables g_PriceTables;
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CBitModel
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitModel
|
||||
{
|
||||
public:
|
||||
UINT32 m_Probability;
|
||||
void UpdateModel(UINT32 aSymbol)
|
||||
{
|
||||
/*
|
||||
m_Probability -= (m_Probability + ((aSymbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
|
||||
m_Probability += (1 - aSymbol) << (kNumBitModelTotalBits - aNumMoveBits);
|
||||
*/
|
||||
if (aSymbol == 0)
|
||||
m_Probability += (kBitModelTotal - m_Probability) >> aNumMoveBits;
|
||||
else
|
||||
m_Probability -= (m_Probability) >> aNumMoveBits;
|
||||
}
|
||||
public:
|
||||
void Init() { m_Probability = kBitModelTotal / 2; }
|
||||
};
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitEncoder: public CBitModel<aNumMoveBits>
|
||||
{
|
||||
public:
|
||||
void Encode(CRangeEncoder *aRangeEncoder, UINT32 aSymbol)
|
||||
{
|
||||
aRangeEncoder->EncodeBit(CBitModel<aNumMoveBits>::m_Probability, kNumBitModelTotalBits, aSymbol);
|
||||
CBitModel<aNumMoveBits>::UpdateModel(aSymbol);
|
||||
}
|
||||
UINT32 GetPrice(UINT32 aSymbol) const
|
||||
{
|
||||
return g_PriceTables.m_StatePrices[
|
||||
(((CBitModel<aNumMoveBits>::m_Probability - aSymbol) ^ ((-(int)aSymbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitDecoder: public CBitModel<aNumMoveBits>
|
||||
{
|
||||
public:
|
||||
UINT32 Decode(CRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aNewBound = (aRangeDecoder->m_Range >> kNumBitModelTotalBits) * CBitModel<aNumMoveBits>::m_Probability;
|
||||
if (aRangeDecoder->m_Code < aNewBound)
|
||||
{
|
||||
aRangeDecoder->m_Range = aNewBound;
|
||||
CBitModel<aNumMoveBits>::m_Probability += (kBitModelTotal - CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
|
||||
if (aRangeDecoder->m_Range < kTopValue)
|
||||
{
|
||||
aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
|
||||
aRangeDecoder->m_Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRangeDecoder->m_Range -= aNewBound;
|
||||
aRangeDecoder->m_Code -= aNewBound;
|
||||
CBitModel<aNumMoveBits>::m_Probability -= (CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
|
||||
if (aRangeDecoder->m_Range < kTopValue)
|
||||
{
|
||||
aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
|
||||
aRangeDecoder->m_Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
33
zsnes/src/jma/ariconst.h
Normal file
33
zsnes/src/jma/ariconst.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ARICONST_H
|
||||
#define __ARICONST_H
|
||||
|
||||
#include "aribitcd.h"
|
||||
|
||||
typedef NCompression::NArithmetic::CRangeEncoder CMyRangeEncoder;
|
||||
typedef NCompression::NArithmetic::CRangeDecoder CMyRangeDecoder;
|
||||
|
||||
template <int aNumMoveBits> class CMyBitEncoder:
|
||||
public NCompression::NArithmetic::CBitEncoder<aNumMoveBits> {};
|
||||
template <int aNumMoveBits> class CMyBitDecoder:
|
||||
public NCompression::NArithmetic::CBitDecoder<aNumMoveBits> {};
|
||||
|
||||
#endif
|
||||
12
zsnes/src/jma/ariprice.h
Normal file
12
zsnes/src/jma/ariprice.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __COMPRESSION_ARIPRICE_H
|
||||
#define __COMPRESSION_ARIPRICE_H
|
||||
|
||||
namespace NCompression {
|
||||
namespace NArithmetic {
|
||||
|
||||
const UINT32 kNumBitPriceShiftBits = 6;
|
||||
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
309
zsnes/src/jma/btreecd.h
Normal file
309
zsnes/src/jma/btreecd.h
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BITTREECODER_H
|
||||
#define __BITTREECODER_H
|
||||
|
||||
#include "aribitcd.h"
|
||||
#include "rcdefs.h"
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder
|
||||
|
||||
template <int aNumMoveBits, UINT32 m_NumBitLevels>
|
||||
class CBitTreeEncoder
|
||||
{
|
||||
CMyBitEncoder<aNumMoveBits> m_Models[1 << m_NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << m_NumBitLevels); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
void Encode(CMyRangeEncoder *aRangeEncoder, UINT32 aSymbol)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0 ;)
|
||||
{
|
||||
aBitIndex--;
|
||||
UINT32 aBit = (aSymbol >> aBitIndex ) & 1;
|
||||
m_Models[aModelIndex].Encode(aRangeEncoder, aBit);
|
||||
aModelIndex = (aModelIndex << 1) | aBit;
|
||||
}
|
||||
};
|
||||
UINT32 GetPrice(UINT32 aSymbol) const
|
||||
{
|
||||
UINT32 aPrice = 0;
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0 ;)
|
||||
{
|
||||
aBitIndex--;
|
||||
UINT32 aBit = (aSymbol >> aBitIndex ) & 1;
|
||||
aPrice += m_Models[aModelIndex].GetPrice(aBit);
|
||||
aModelIndex = (aModelIndex << 1) + aBit;
|
||||
}
|
||||
return aPrice;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder
|
||||
|
||||
template <int aNumMoveBits, UINT32 m_NumBitLevels>
|
||||
class CBitTreeDecoder
|
||||
{
|
||||
CMyBitDecoder<aNumMoveBits> m_Models[1 << m_NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << m_NumBitLevels); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0; aBitIndex--)
|
||||
{
|
||||
// aModelIndex = (aModelIndex << 1) + m_Models[aModelIndex].Decode(aRangeDecoder);
|
||||
RC_GETBIT(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return aModelIndex - (1 << m_NumBitLevels);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeEncoder
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CReverseBitTreeEncoder2
|
||||
{
|
||||
CMyBitEncoder<aNumMoveBits> *m_Models;
|
||||
UINT32 m_NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeEncoder2(): m_Models(0) { }
|
||||
~CReverseBitTreeEncoder2() { delete []m_Models; }
|
||||
bool Create(UINT32 aNumBitLevels)
|
||||
{
|
||||
m_NumBitLevels = aNumBitLevels;
|
||||
m_Models = new CMyBitEncoder<aNumMoveBits>[1 << aNumBitLevels];
|
||||
return (m_Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 aNumModels = 1 << m_NumBitLevels;
|
||||
for(UINT32 i = 1; i < aNumModels; i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
void Encode(CMyRangeEncoder *aRangeEncoder, UINT32 aSymbol)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 i = 0; i < m_NumBitLevels; i++)
|
||||
{
|
||||
UINT32 aBit = aSymbol & 1;
|
||||
m_Models[aModelIndex].Encode(aRangeEncoder, aBit);
|
||||
aModelIndex = (aModelIndex << 1) | aBit;
|
||||
aSymbol >>= 1;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 aSymbol) const
|
||||
{
|
||||
UINT32 aPrice = 0;
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 i = m_NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UINT32 aBit = aSymbol & 1;
|
||||
aSymbol >>= 1;
|
||||
aPrice += m_Models[aModelIndex].GetPrice(aBit);
|
||||
aModelIndex = (aModelIndex << 1) | aBit;
|
||||
}
|
||||
return aPrice;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <int aNumMoveBits, int aNumBitLevels>
|
||||
class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<aNumMoveBits>
|
||||
{
|
||||
public:
|
||||
CReverseBitTreeEncoder()
|
||||
{ Create(aNumBitLevels); }
|
||||
};
|
||||
*/
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeDecoder
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CReverseBitTreeDecoder2
|
||||
{
|
||||
CMyBitDecoder<aNumMoveBits> *m_Models;
|
||||
UINT32 m_NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeDecoder2(): m_Models(0) { }
|
||||
~CReverseBitTreeDecoder2() { delete []m_Models; }
|
||||
bool Create(UINT32 aNumBitLevels)
|
||||
{
|
||||
m_NumBitLevels = aNumBitLevels;
|
||||
m_Models = new CMyBitDecoder<aNumMoveBits>[1 << aNumBitLevels];
|
||||
return (m_Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 aNumModels = 1 << m_NumBitLevels;
|
||||
for(UINT32 i = 1; i < aNumModels; i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
UINT32 aSymbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 aBitIndex = 0; aBitIndex < m_NumBitLevels; aBitIndex++)
|
||||
{
|
||||
// UINT32 aBit = m_Models[aModelIndex].Decode(aRangeDecoder);
|
||||
// aModelIndex <<= 1;
|
||||
// aModelIndex += aBit;
|
||||
// aSymbol |= (aBit << aBitIndex);
|
||||
RC_GETBIT2(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex, ; , aSymbol |= (1 << aBitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return aSymbol;
|
||||
};
|
||||
};
|
||||
////////////////////////////
|
||||
// CReverseBitTreeDecoder2
|
||||
|
||||
template <int aNumMoveBits, UINT32 m_NumBitLevels>
|
||||
class CReverseBitTreeDecoder
|
||||
{
|
||||
CMyBitDecoder<aNumMoveBits> m_Models[1 << m_NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << m_NumBitLevels); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
UINT32 aSymbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 aBitIndex = 0; aBitIndex < m_NumBitLevels; aBitIndex++)
|
||||
{
|
||||
// UINT32 aBit = m_Models[aModelIndex].Decode(aRangeDecoder);
|
||||
// aModelIndex <<= 1;
|
||||
// aModelIndex += aBit;
|
||||
// aSymbol |= (aBit << aBitIndex);
|
||||
RC_GETBIT2(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex, ; , aSymbol |= (1 << aBitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return aSymbol;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder2
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitTreeEncoder2
|
||||
{
|
||||
NCompression::NArithmetic::CBitEncoder<aNumMoveBits> *m_Models;
|
||||
UINT32 m_NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 aNumBitLevels)
|
||||
{
|
||||
m_NumBitLevels = aNumBitLevels;
|
||||
m_Models = new NCompression::NArithmetic::CBitEncoder<aNumMoveBits>[1 << aNumBitLevels];
|
||||
return (m_Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 aNumModels = 1 << m_NumBitLevels;
|
||||
for(UINT32 i = 1; i < aNumModels; i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
void Encode(CMyRangeEncoder *aRangeEncoder, UINT32 aSymbol)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0 ;)
|
||||
{
|
||||
aBitIndex--;
|
||||
UINT32 aBit = (aSymbol >> aBitIndex ) & 1;
|
||||
m_Models[aModelIndex].Encode(aRangeEncoder, aBit);
|
||||
aModelIndex = (aModelIndex << 1) | aBit;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 aSymbol) const
|
||||
{
|
||||
UINT32 aPrice = 0;
|
||||
UINT32 aModelIndex = 1;
|
||||
for (UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0 ;)
|
||||
{
|
||||
aBitIndex--;
|
||||
UINT32 aBit = (aSymbol >> aBitIndex ) & 1;
|
||||
aPrice += m_Models[aModelIndex].GetPrice(aBit);
|
||||
aModelIndex = (aModelIndex << 1) + aBit;
|
||||
}
|
||||
return aPrice;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder2
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitTreeDecoder2
|
||||
{
|
||||
NCompression::NArithmetic::CBitDecoder<aNumMoveBits> *m_Models;
|
||||
UINT32 m_NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 aNumBitLevels)
|
||||
{
|
||||
m_NumBitLevels = aNumBitLevels;
|
||||
m_Models = new NCompression::NArithmetic::CBitDecoder<aNumMoveBits>[1 << aNumBitLevels];
|
||||
return (m_Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 aNumModels = 1 << m_NumBitLevels;
|
||||
for(UINT32 i = 1; i < aNumModels; i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aModelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0; aBitIndex--)
|
||||
{
|
||||
// aModelIndex = (aModelIndex << 1) + m_Models[aModelIndex].Decode(aRangeDecoder);
|
||||
RC_GETBIT(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return aModelIndex - (1 << m_NumBitLevels);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
82
zsnes/src/jma/crc32.cpp
Normal file
82
zsnes/src/jma/crc32.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace CRC32lib
|
||||
{
|
||||
//Don't ask questions, this is the PKZip CRC32 table
|
||||
const unsigned int crc32Table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
|
||||
|
||||
|
||||
//CRC32 for char arrays
|
||||
unsigned int CRC32(const unsigned char *array, size_t size, register unsigned int crc32)
|
||||
{
|
||||
const unsigned char *end_p = array+size;
|
||||
for (register const unsigned char *p = array; p < end_p; p++)
|
||||
{
|
||||
crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ *p) & 0xFF];
|
||||
}
|
||||
|
||||
return(~crc32);
|
||||
}
|
||||
}
|
||||
29
zsnes/src/jma/crc32.h
Normal file
29
zsnes/src/jma/crc32.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
namespace CRC32lib
|
||||
{
|
||||
unsigned int CRC32(const unsigned char *, size_t, register unsigned int crc32 = 0xFFFFFFFF);
|
||||
unsigned short SUM_CRC32(const unsigned char *, size_t, unsigned int &crc32);
|
||||
}
|
||||
|
||||
#endif
|
||||
44
zsnes/src/jma/iiostrm.cpp
Normal file
44
zsnes/src/jma/iiostrm.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
#include "iiostrm.h"
|
||||
|
||||
HRESULT ISequentialInStream::Read(void *aData, UINT32 aSize, UINT32* aProcessedSize) {
|
||||
if (aSize > size)
|
||||
aSize = size;
|
||||
*aProcessedSize = aSize;
|
||||
memcpy(aData, data, aSize);
|
||||
size -= aSize;
|
||||
data += aSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ISequentialOutStream::Write(const void *aData, UINT32 aSize, UINT32* aProcessedSize) {
|
||||
if (aSize > size) {
|
||||
overflow = true;
|
||||
aSize = size;
|
||||
}
|
||||
*aProcessedSize = aSize;
|
||||
memcpy(data, aData, aSize);
|
||||
size -= aSize;
|
||||
data += aSize;
|
||||
total += aSize;
|
||||
return S_OK;
|
||||
}
|
||||
50
zsnes/src/jma/iiostrm.h
Normal file
50
zsnes/src/jma/iiostrm.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __IINOUTSTREAMS_H
|
||||
#define __IINOUTSTREAMS_H
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
class ISequentialInStream
|
||||
{
|
||||
const char* data;
|
||||
unsigned size;
|
||||
public:
|
||||
ISequentialInStream(const char* Adata, unsigned Asize) : data(Adata), size(Asize) { }
|
||||
|
||||
HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
};
|
||||
|
||||
class ISequentialOutStream
|
||||
{
|
||||
char* data;
|
||||
unsigned size;
|
||||
bool overflow;
|
||||
unsigned total;
|
||||
public:
|
||||
ISequentialOutStream(char* Adata, unsigned Asize) : data(Adata), size(Asize), overflow(false), total(0) { }
|
||||
|
||||
bool overflow_get() const { return overflow; }
|
||||
unsigned size_get() const { return total; }
|
||||
|
||||
HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
60
zsnes/src/jma/inbyte.cpp
Normal file
60
zsnes/src/jma/inbyte.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "inbyte.h"
|
||||
|
||||
namespace NStream{
|
||||
|
||||
CInByte::CInByte(UINT32 aBufferSize):
|
||||
m_BufferSize(aBufferSize),
|
||||
m_BufferBase(0)
|
||||
{
|
||||
m_BufferBase = new BYTE[m_BufferSize];
|
||||
}
|
||||
|
||||
CInByte::~CInByte()
|
||||
{
|
||||
delete []m_BufferBase;
|
||||
}
|
||||
|
||||
void CInByte::Init(ISequentialInStream *aStream)
|
||||
{
|
||||
m_Stream = aStream;
|
||||
m_ProcessedSize = 0;
|
||||
m_Buffer = m_BufferBase;
|
||||
m_BufferLimit = m_Buffer;
|
||||
m_StreamWasExhausted = false;
|
||||
}
|
||||
|
||||
bool CInByte::ReadBlock()
|
||||
{
|
||||
if (m_StreamWasExhausted)
|
||||
return false;
|
||||
m_ProcessedSize += (m_Buffer - m_BufferBase);
|
||||
UINT32 aNumProcessedBytes;
|
||||
HRESULT aResult = m_Stream->Read(m_BufferBase, m_BufferSize, &aNumProcessedBytes);
|
||||
if (aResult != S_OK)
|
||||
throw aResult;
|
||||
m_Buffer = m_BufferBase;
|
||||
m_BufferLimit = m_Buffer + aNumProcessedBytes;
|
||||
m_StreamWasExhausted = (aNumProcessedBytes == 0);
|
||||
return (!m_StreamWasExhausted);
|
||||
}
|
||||
|
||||
}
|
||||
77
zsnes/src/jma/inbyte.h
Normal file
77
zsnes/src/jma/inbyte.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_INBYTE_H
|
||||
#define __STREAM_INBYTE_H
|
||||
|
||||
#include "iiostrm.h"
|
||||
|
||||
namespace NStream {
|
||||
|
||||
class CInByte
|
||||
{
|
||||
UINT64 m_ProcessedSize;
|
||||
BYTE *m_BufferBase;
|
||||
UINT32 m_BufferSize;
|
||||
BYTE *m_Buffer;
|
||||
BYTE *m_BufferLimit;
|
||||
ISequentialInStream* m_Stream;
|
||||
bool m_StreamWasExhausted;
|
||||
|
||||
bool ReadBlock();
|
||||
|
||||
public:
|
||||
CInByte(UINT32 aBufferSize = 0x100000);
|
||||
~CInByte();
|
||||
|
||||
void Init(ISequentialInStream *aStream);
|
||||
|
||||
bool ReadByte(BYTE &aByte)
|
||||
{
|
||||
if(m_Buffer >= m_BufferLimit)
|
||||
if(!ReadBlock())
|
||||
return false;
|
||||
aByte = *m_Buffer++;
|
||||
return true;
|
||||
}
|
||||
BYTE ReadByte()
|
||||
{
|
||||
if(m_Buffer >= m_BufferLimit)
|
||||
if(!ReadBlock())
|
||||
return 0x0;
|
||||
return *m_Buffer++;
|
||||
}
|
||||
void ReadBytes(void *aData, UINT32 aSize, UINT32 &aProcessedSize)
|
||||
{
|
||||
for(aProcessedSize = 0; aProcessedSize < aSize; aProcessedSize++)
|
||||
if (!ReadByte(((BYTE *)aData)[aProcessedSize]))
|
||||
return;
|
||||
}
|
||||
bool ReadBytes(void *aData, UINT32 aSize)
|
||||
{
|
||||
UINT32 aProcessedSize;
|
||||
ReadBytes(aData, aSize, aProcessedSize);
|
||||
return (aProcessedSize == aSize);
|
||||
}
|
||||
UINT64 GetProcessedSize() const { return m_ProcessedSize + (m_Buffer - m_BufferBase); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
447
zsnes/src/jma/jma.cpp
Normal file
447
zsnes/src/jma/jma.cpp
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "jma.h"
|
||||
using namespace std;
|
||||
|
||||
#include "portable.h"
|
||||
#include "7z.h"
|
||||
#include "crc32.h"
|
||||
|
||||
namespace JMA
|
||||
{
|
||||
const char jma_magic[] = { 'J', 'M', 'A', 0, 'N' };
|
||||
const unsigned char jma_version = 0;
|
||||
const unsigned char jma_null = 0;
|
||||
|
||||
//Convert zip/JMA integer time to to time_t
|
||||
time_t uint_to_time(unsigned int date, unsigned int time)
|
||||
{
|
||||
tm formatted_time;
|
||||
|
||||
formatted_time.tm_mday = date & 0x1F;
|
||||
formatted_time.tm_mon = ((date >> 5) & 0xF) - 1;
|
||||
formatted_time.tm_year = ((date >> 9) & 0x7f) + 80;
|
||||
formatted_time.tm_sec = (time & 0x1F) * 2;
|
||||
formatted_time.tm_min = (time >> 5) & 0x3F;
|
||||
formatted_time.tm_hour = (time >> 11) & 0x1F;
|
||||
|
||||
return(mktime(&formatted_time));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Retreive the file block, what else?
|
||||
void jma_open::retrieve_file_block() throw(jma_errors)
|
||||
{
|
||||
unsigned char uint_buffer[UINT_SIZE];
|
||||
|
||||
//File block size is the last UINT in the file
|
||||
stream.seekg(-UINT_SIZE,ios::end);
|
||||
stream.read((char *)uint_buffer, UINT_SIZE);
|
||||
size_t file_block_size = charp_to_uint(uint_buffer);
|
||||
|
||||
//Currently at the end of the file, so that's the file size
|
||||
size_t jma_file_size = stream.tellg();
|
||||
|
||||
//The file block can't be larger than the JMA file.
|
||||
//This if can probably be improved
|
||||
if (file_block_size >= jma_file_size)
|
||||
{
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//Seek to before file block so we can read the file block
|
||||
stream.seekg(-(file_block_size+UINT_SIZE),ios::end);
|
||||
|
||||
jma_file_info file_info;
|
||||
char byte;
|
||||
|
||||
while (file_block_size)
|
||||
{
|
||||
//First stored in the file block is the file name null terminated
|
||||
file_info.name = "";
|
||||
|
||||
stream.get(byte);
|
||||
while (byte)
|
||||
{
|
||||
file_info.name += byte;
|
||||
stream.get(byte);
|
||||
}
|
||||
|
||||
//There must be a file name or the file is bad
|
||||
if (!file_info.name.length())
|
||||
{
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//Same trick as above for the comment
|
||||
file_info.comment = "";
|
||||
|
||||
stream.get(byte);
|
||||
while (byte)
|
||||
{
|
||||
file_info.comment += byte;
|
||||
stream.get(byte);
|
||||
}
|
||||
|
||||
//Next is a UINT representing the file's size
|
||||
stream.read((char *)uint_buffer, UINT_SIZE);
|
||||
file_info.size = charp_to_uint(uint_buffer);
|
||||
|
||||
//Followed by CRC32
|
||||
stream.read((char *)uint_buffer, UINT_SIZE);
|
||||
file_info.crc32 = charp_to_uint(uint_buffer);
|
||||
|
||||
//Special UINT representation of file's date
|
||||
stream.read((char *)uint_buffer, UINT_SIZE);
|
||||
file_info.date = charp_to_uint(uint_buffer);
|
||||
|
||||
//Special UINT representation of file's time
|
||||
stream.read((char *)uint_buffer, UINT_SIZE);
|
||||
file_info.time = charp_to_uint(uint_buffer);
|
||||
|
||||
file_info.buffer = 0; //Pointing to null till we decompress files
|
||||
|
||||
files.push_back(file_info); //Put file info into our structure
|
||||
|
||||
//Subtract size of the file info we just read
|
||||
file_block_size -= file_info.name.length()+file_info.comment.length()+2+UINT_SIZE*4;
|
||||
}
|
||||
}
|
||||
|
||||
//Constructor for opening JMA files for reading
|
||||
jma_open::jma_open(const char *compressed_file_name) throw (jma_errors)
|
||||
{
|
||||
decompressed_buffer = 0;
|
||||
compressed_buffer = 0;
|
||||
|
||||
stream.open(compressed_file_name, ios::in | ios::binary);
|
||||
if (!stream)
|
||||
{
|
||||
throw(JMA_NO_OPEN);
|
||||
}
|
||||
|
||||
//Header is "JMA\0N"
|
||||
unsigned char header[5];
|
||||
stream.read((char *)header, 5);
|
||||
if (memcmp(jma_magic, header, 5))
|
||||
{
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//Not the cleanest code but logical
|
||||
stream.read((char *)header, 5);
|
||||
if (*header == 0) //Version 0
|
||||
{
|
||||
chunk_size = charp_to_uint(header+1); //Chunk size is a UINT that follows version #
|
||||
retrieve_file_block();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw(JMA_UNSUPPORTED_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
//Destructor only has to close the stream if neccesary
|
||||
jma_open::~jma_open()
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
//Return a vector containing useful info about the files in the JMA
|
||||
vector<jma_public_file_info> jma_open::get_files_info()
|
||||
{
|
||||
vector<jma_public_file_info> file_info_vector;
|
||||
jma_public_file_info file_info;
|
||||
|
||||
for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
file_info.name = i->name;
|
||||
file_info.comment = i->comment;
|
||||
file_info.size = i->size;
|
||||
file_info.datetime = uint_to_time(i->date, i->time);
|
||||
file_info.crc32 = i->crc32;
|
||||
file_info_vector.push_back(file_info);
|
||||
}
|
||||
|
||||
return(file_info_vector);
|
||||
}
|
||||
|
||||
//Skip forward a given number of chunks
|
||||
void jma_open::chunk_seek(unsigned int chunk_num) throw(jma_errors)
|
||||
{
|
||||
//Check the stream is open
|
||||
if (!stream)
|
||||
{
|
||||
throw(JMA_NO_OPEN);
|
||||
}
|
||||
|
||||
//Move forward over header
|
||||
stream.seekg(10, ios::beg);
|
||||
|
||||
unsigned char int4_buffer[UINT_SIZE];
|
||||
|
||||
while (chunk_num--)
|
||||
{
|
||||
//Read in size of chunk
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
|
||||
//Skip chunk plus it's CRC32
|
||||
stream.seekg(charp_to_uint(int4_buffer)+UINT_SIZE, ios::cur);
|
||||
}
|
||||
}
|
||||
|
||||
//Return a vector of pointers to each file in the JMA, the buffer to hold all the files
|
||||
//must be initilized outside.
|
||||
vector<unsigned char *> jma_open::get_all_files(unsigned char *buffer) throw(jma_errors)
|
||||
{
|
||||
//If there's no stream we can't read from it, so exit
|
||||
if (!stream)
|
||||
{
|
||||
throw(JMA_NO_OPEN);
|
||||
}
|
||||
|
||||
//Seek to the first chunk
|
||||
chunk_seek(0);
|
||||
|
||||
//Set the buffer that decompressed data goes to
|
||||
decompressed_buffer = buffer;
|
||||
|
||||
//If the JMA is not solid
|
||||
if (chunk_size)
|
||||
{
|
||||
unsigned char int4_buffer[UINT_SIZE];
|
||||
size_t size = get_total_size(files);
|
||||
|
||||
//For each chunk in the file...
|
||||
for (size_t remaining_size = size; remaining_size; remaining_size -= chunk_size)
|
||||
{
|
||||
//Read the compressed size
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
size_t compressed_size = charp_to_uint(int4_buffer);
|
||||
|
||||
//Allocate memory of the correct size to hold the compressed data in the JMA
|
||||
//Throw error on failure as that is unrecoverable from
|
||||
try
|
||||
{
|
||||
compressed_buffer = new unsigned char[compressed_size];
|
||||
}
|
||||
catch (bad_alloc xa)
|
||||
{
|
||||
throw(JMA_NO_MEM_ALLOC);
|
||||
}
|
||||
|
||||
//Read all the compressed data in
|
||||
stream.read((char *)compressed_buffer, compressed_size);
|
||||
|
||||
//Read the expected CRC of compressed data from the file
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
|
||||
//If it doesn't match, throw error and cleanup memory
|
||||
if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer))
|
||||
{
|
||||
delete[] compressed_buffer;
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//Decompress the data, cleanup memory on failure
|
||||
if (!decompress_lzma_7z(compressed_buffer, compressed_size,
|
||||
decompressed_buffer+size-remaining_size,
|
||||
(remaining_size > chunk_size) ? chunk_size : remaining_size))
|
||||
{
|
||||
delete[] compressed_buffer;
|
||||
throw(JMA_DECOMPRESS_FAILED);
|
||||
}
|
||||
delete[] compressed_buffer;
|
||||
}
|
||||
}
|
||||
else //Solidly compressed JMA
|
||||
{
|
||||
unsigned char int4_buffer[UINT_SIZE];
|
||||
|
||||
//read the size of the compressed data
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
size_t compressed_size = charp_to_uint(int4_buffer);
|
||||
|
||||
//Allocate memory of the right size to hold the compressed data in the JMA
|
||||
try
|
||||
{
|
||||
compressed_buffer = new unsigned char[compressed_size];
|
||||
}
|
||||
catch (bad_alloc xa)
|
||||
{
|
||||
throw(JMA_NO_MEM_ALLOC);
|
||||
}
|
||||
|
||||
//Copy the compressed data into memory
|
||||
stream.read((char *)compressed_buffer, compressed_size);
|
||||
size_t size = get_total_size(files);
|
||||
|
||||
//Read the CRC of the compressed data
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
|
||||
//If it doesn't match, complain
|
||||
if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer))
|
||||
{
|
||||
delete[] compressed_buffer;
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//decompress the data
|
||||
if (!decompress_lzma_7z(compressed_buffer, compressed_size, decompressed_buffer, size))
|
||||
{
|
||||
delete[] compressed_buffer;
|
||||
throw(JMA_DECOMPRESS_FAILED);
|
||||
}
|
||||
delete[] compressed_buffer;
|
||||
}
|
||||
|
||||
vector<unsigned char *> file_pointers;
|
||||
size_t size = 0;
|
||||
|
||||
//For each file, add it's pointer to the vector, size is pointer offset in the buffer
|
||||
for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
i->buffer = decompressed_buffer+size;
|
||||
file_pointers.push_back(decompressed_buffer+size);
|
||||
size += i->size;
|
||||
}
|
||||
|
||||
//Return the vector of pointers
|
||||
return(file_pointers);
|
||||
}
|
||||
|
||||
//Extracts the file with a given name found in the archive to the given buffer
|
||||
void jma_open::extract_file(string& name, unsigned char *buffer) throw(jma_errors)
|
||||
{
|
||||
if (!stream)
|
||||
{
|
||||
throw(JMA_NO_OPEN);
|
||||
}
|
||||
|
||||
size_t size_to_skip = 0;
|
||||
size_t our_file_size = 0;
|
||||
|
||||
//Search through the vector of file information
|
||||
for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
if (i->name == name)
|
||||
{
|
||||
//Set the variable so we can tell we found it
|
||||
our_file_size = i->size;
|
||||
break;
|
||||
}
|
||||
|
||||
//Keep a running total of size
|
||||
size_to_skip += i->size;
|
||||
}
|
||||
|
||||
if (!our_file_size) //File with the specified name was not found in the archive
|
||||
{
|
||||
throw(JMA_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (chunk_size) //we are using non-solid archive..
|
||||
{
|
||||
unsigned int chunks_to_skip = size_to_skip / chunk_size;
|
||||
|
||||
//skip over requisite number of chunks
|
||||
chunk_seek(chunks_to_skip);
|
||||
|
||||
//Allocate memory for compressed and decompressed data
|
||||
unsigned char *comp_buffer = 0, *decomp_buffer = 0;
|
||||
try
|
||||
{
|
||||
//Compressed data size is <= non compressed size
|
||||
unsigned char *combined_buffer = new unsigned char[chunk_size*2];
|
||||
comp_buffer = combined_buffer;
|
||||
decomp_buffer = combined_buffer+chunk_size;
|
||||
}
|
||||
catch (bad_alloc xa)
|
||||
{
|
||||
throw(JMA_NO_MEM_ALLOC);
|
||||
}
|
||||
|
||||
size_t first_chunk_offset = size_to_skip % chunk_size;
|
||||
unsigned char int4_buffer[UINT_SIZE];
|
||||
for (size_t i = 0; i < our_file_size;)
|
||||
{
|
||||
//Get size
|
||||
stream.read((char *) int4_buffer, UINT_SIZE);
|
||||
size_t compressed_size = charp_to_uint(int4_buffer);
|
||||
|
||||
//Read all the compressed data in
|
||||
stream.read((char *)comp_buffer, compressed_size);
|
||||
|
||||
//Read the CRC of the compressed data
|
||||
stream.read((char *)int4_buffer, UINT_SIZE);
|
||||
|
||||
//If it doesn't match, complain
|
||||
if (CRC32lib::CRC32(comp_buffer, compressed_size) != charp_to_uint(int4_buffer))
|
||||
{
|
||||
delete[] comp_buffer;
|
||||
throw(JMA_BAD_FILE);
|
||||
}
|
||||
|
||||
//Decompress chunk
|
||||
if (!decompress_lzma_7z(comp_buffer, compressed_size, decomp_buffer, chunk_size))
|
||||
{
|
||||
delete[] comp_buffer;
|
||||
throw(JMA_DECOMPRESS_FAILED);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t copy_amount = our_file_size-i > chunk_size ? chunk_size : our_file_size-i;
|
||||
copy_amount -= first_chunk_offset;
|
||||
memcpy(buffer+i, decomp_buffer+first_chunk_offset, copy_amount);
|
||||
first_chunk_offset = 0;
|
||||
i += copy_amount;
|
||||
}
|
||||
}
|
||||
delete[] comp_buffer;
|
||||
}
|
||||
else //Solid JMA
|
||||
{
|
||||
unsigned char *decomp_buffer = 0;
|
||||
try
|
||||
{
|
||||
decomp_buffer = new unsigned char[get_total_size(files)];
|
||||
}
|
||||
catch (bad_alloc xa)
|
||||
{
|
||||
throw(JMA_NO_MEM_ALLOC);
|
||||
}
|
||||
|
||||
get_all_files(decomp_buffer);
|
||||
|
||||
memcpy(buffer, decomp_buffer+size_to_skip, our_file_size);
|
||||
|
||||
delete[] decomp_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
88
zsnes/src/jma/jma.h
Normal file
88
zsnes/src/jma/jma.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef JMA_H
|
||||
#define JMA_H
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <time.h>
|
||||
|
||||
namespace JMA
|
||||
{
|
||||
enum jma_errors { JMA_NO_CREATE, JMA_NO_MEM_ALLOC, JMA_NO_OPEN, JMA_BAD_FILE,
|
||||
JMA_UNSUPPORTED_VERSION, JMA_COMPRESS_FAILED, JMA_DECOMPRESS_FAILED,
|
||||
JMA_FILE_NOT_FOUND };
|
||||
|
||||
struct jma_file_info_base
|
||||
{
|
||||
std::string name;
|
||||
std::string comment;
|
||||
size_t size;
|
||||
unsigned int crc32;
|
||||
};
|
||||
|
||||
struct jma_public_file_info : jma_file_info_base
|
||||
{
|
||||
time_t datetime;
|
||||
};
|
||||
|
||||
struct jma_file_info : jma_file_info_base
|
||||
{
|
||||
unsigned int date;
|
||||
unsigned int time;
|
||||
const unsigned char *buffer;
|
||||
};
|
||||
|
||||
template<class jma_file_type>
|
||||
inline size_t get_total_size(std::vector<jma_file_type>& files)
|
||||
{
|
||||
size_t size = 0;
|
||||
for (typename std::vector<jma_file_type>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
size += i->size; //We do have a problem if this wraps around
|
||||
}
|
||||
|
||||
return(size);
|
||||
}
|
||||
|
||||
class jma_open
|
||||
{
|
||||
public:
|
||||
jma_open(const char *) throw(jma_errors);
|
||||
~jma_open();
|
||||
|
||||
std::vector<jma_public_file_info> get_files_info();
|
||||
std::vector<unsigned char *> get_all_files(unsigned char *) throw(jma_errors);
|
||||
void extract_file(std::string& name, unsigned char *) throw(jma_errors);
|
||||
|
||||
private:
|
||||
std::ifstream stream;
|
||||
std::vector<jma_file_info> files;
|
||||
size_t chunk_size;
|
||||
unsigned char *decompressed_buffer;
|
||||
unsigned char *compressed_buffer;
|
||||
|
||||
void chunk_seek(unsigned int) throw(jma_errors);
|
||||
void retrieve_file_block() throw(jma_errors);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
93
zsnes/src/jma/lencoder.h
Normal file
93
zsnes/src/jma/lencoder.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LENCODER_H
|
||||
#define __LENCODER_H
|
||||
|
||||
#include "btreecd.h"
|
||||
|
||||
namespace NLength {
|
||||
|
||||
const int kNumPosStatesBitsMax = 4;
|
||||
const int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
|
||||
|
||||
const int kNumPosStatesBitsEncodingMax = 4;
|
||||
const int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
const int kNumLenBits = 3;
|
||||
const int kNumLowSymbols = 1 << kNumLenBits;
|
||||
const int kNumMidBits = 3;
|
||||
const int kNumMidSymbols = 1 << kNumMidBits;
|
||||
|
||||
const int kNumHighBits = 8;
|
||||
|
||||
const int kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
|
||||
|
||||
const int kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
CMyBitDecoder<kNumMoveBits> m_Choice;
|
||||
CBitTreeDecoder<kNumMoveBits, kNumLenBits> m_LowCoder[kNumPosStatesMax];
|
||||
CMyBitDecoder<kNumMoveBits> m_Choice2;
|
||||
CBitTreeDecoder<kNumMoveBits, kNumMidBits> m_MidCoder[kNumPosStatesMax];
|
||||
CBitTreeDecoder<kNumMoveBits, kNumHighBits> m_HighCoder;
|
||||
UINT32 m_NumPosStates;
|
||||
public:
|
||||
void Create(UINT32 aNumPosStates)
|
||||
{ m_NumPosStates = aNumPosStates; }
|
||||
void Init()
|
||||
{
|
||||
m_Choice.Init();
|
||||
for (UINT32 aPosState = 0; aPosState < m_NumPosStates; aPosState++)
|
||||
{
|
||||
m_LowCoder[aPosState].Init();
|
||||
m_MidCoder[aPosState].Init();
|
||||
}
|
||||
m_Choice2.Init();
|
||||
m_HighCoder.Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *aRangeDecoder, UINT32 aPosState)
|
||||
{
|
||||
if(m_Choice.Decode(aRangeDecoder) == 0)
|
||||
return m_LowCoder[aPosState].Decode(aRangeDecoder);
|
||||
else
|
||||
{
|
||||
UINT32 aSymbol = kNumLowSymbols;
|
||||
if(m_Choice2.Decode(aRangeDecoder) == 0)
|
||||
aSymbol += m_MidCoder[aPosState].Decode(aRangeDecoder);
|
||||
else
|
||||
{
|
||||
aSymbol += kNumMidSymbols;
|
||||
aSymbol += m_HighCoder.Decode(aRangeDecoder);
|
||||
}
|
||||
return aSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
123
zsnes/src/jma/litcoder.h
Normal file
123
zsnes/src/jma/litcoder.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LITERALCODER_H
|
||||
#define __LITERALCODER_H
|
||||
|
||||
#include "aribitcd.h"
|
||||
#include "rcdefs.h"
|
||||
|
||||
namespace NLiteral {
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
class CDecoder2
|
||||
{
|
||||
CMyBitDecoder<kNumMoveBits> m_Decoders[3][1 << 8];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 1; j < (1 << 8); j++)
|
||||
m_Decoders[i][j].Init();
|
||||
}
|
||||
|
||||
BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder)
|
||||
{
|
||||
UINT32 aSymbol = 1;
|
||||
RC_INIT_VAR
|
||||
do
|
||||
{
|
||||
// aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder);
|
||||
RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol)
|
||||
}
|
||||
while (aSymbol < 0x100);
|
||||
RC_FLUSH_VAR
|
||||
return aSymbol;
|
||||
}
|
||||
|
||||
BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, BYTE aMatchByte)
|
||||
{
|
||||
UINT32 aSymbol = 1;
|
||||
RC_INIT_VAR
|
||||
do
|
||||
{
|
||||
UINT32 aMatchBit = (aMatchByte >> 7) & 1;
|
||||
aMatchByte <<= 1;
|
||||
// UINT32 aBit = m_Decoders[1 + aMatchBit][aSymbol].Decode(aRangeDecoder);
|
||||
// aSymbol = (aSymbol << 1) | aBit;
|
||||
UINT32 aBit;
|
||||
RC_GETBIT2(kNumMoveBits, m_Decoders[1 + aMatchBit][aSymbol].m_Probability, aSymbol,
|
||||
aBit = 0, aBit = 1)
|
||||
if (aMatchBit != aBit)
|
||||
{
|
||||
while (aSymbol < 0x100)
|
||||
{
|
||||
// aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder);
|
||||
RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (aSymbol < 0x100);
|
||||
RC_FLUSH_VAR
|
||||
return aSymbol;
|
||||
}
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
CDecoder2 *m_Coders;
|
||||
UINT32 m_NumPrevBits;
|
||||
UINT32 m_NumPosBits;
|
||||
UINT32 m_PosMask;
|
||||
public:
|
||||
CDecoder(): m_Coders(0) {}
|
||||
~CDecoder() { Free(); }
|
||||
void Free()
|
||||
{
|
||||
delete []m_Coders;
|
||||
m_Coders = 0;
|
||||
}
|
||||
void Create(UINT32 aNumPosBits, UINT32 aNumPrevBits)
|
||||
{
|
||||
Free();
|
||||
m_NumPosBits = aNumPosBits;
|
||||
m_PosMask = (1 << aNumPosBits) - 1;
|
||||
m_NumPrevBits = aNumPrevBits;
|
||||
UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
m_Coders = new CDecoder2[aNumStates];
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
||||
for (UINT32 i = 0; i < aNumStates; i++)
|
||||
m_Coders[i].Init();
|
||||
}
|
||||
UINT32 GetState(UINT32 aPos, BYTE aPrevByte) const
|
||||
{ return ((aPos & m_PosMask) << m_NumPrevBits) + (aPrevByte >> (8 - m_NumPrevBits)); }
|
||||
BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte)
|
||||
{ return m_Coders[GetState(aPos, aPrevByte)].DecodeNormal(aRangeDecoder); }
|
||||
BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte, BYTE aMatchByte)
|
||||
{ return m_Coders[GetState(aPos, aPrevByte)].DecodeWithMatchByte(aRangeDecoder, aMatchByte); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
42
zsnes/src/jma/lzma.cpp
Normal file
42
zsnes/src/jma/lzma.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lzma.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
UINT32 kDistStart[kDistTableSizeMax];
|
||||
|
||||
static class CConstInit
|
||||
{
|
||||
public:
|
||||
CConstInit()
|
||||
{
|
||||
UINT32 aStartValue = 0;
|
||||
int i;
|
||||
for (i = 0; i < kDistTableSizeMax; i++)
|
||||
{
|
||||
kDistStart[i] = aStartValue;
|
||||
aStartValue += (1 << kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
} g_ConstInit;
|
||||
|
||||
}}
|
||||
124
zsnes/src/jma/lzma.h
Normal file
124
zsnes/src/jma/lzma.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lencoder.h"
|
||||
|
||||
#ifndef __LZMA_H
|
||||
#define __LZMA_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
const UINT32 kNumRepDistances = 4;
|
||||
|
||||
const BYTE kNumStates = 12;
|
||||
|
||||
const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
const BYTE kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
const BYTE kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
|
||||
class CState
|
||||
{
|
||||
public:
|
||||
BYTE m_Index;
|
||||
void Init()
|
||||
{ m_Index = 0; }
|
||||
void UpdateChar()
|
||||
{ m_Index = kLiteralNextStates[m_Index]; }
|
||||
void UpdateMatch()
|
||||
{ m_Index = kMatchNextStates[m_Index]; }
|
||||
void UpdateRep()
|
||||
{ m_Index = kRepNextStates[m_Index]; }
|
||||
void UpdateShortRep()
|
||||
{ m_Index = kShortRepNextStates[m_Index]; }
|
||||
};
|
||||
|
||||
class CBaseCoder
|
||||
{
|
||||
protected:
|
||||
CState m_State;
|
||||
BYTE m_PreviousByte;
|
||||
bool m_PeviousIsMatch;
|
||||
UINT32 m_RepDistances[kNumRepDistances];
|
||||
void Init()
|
||||
{
|
||||
m_State.Init();
|
||||
m_PreviousByte = 0;
|
||||
m_PeviousIsMatch = false;
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
m_RepDistances[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
const int kNumPosSlotBits = 6;
|
||||
const int kDicLogSizeMax = 28;
|
||||
const int kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
extern UINT32 kDistStart[kDistTableSizeMax];
|
||||
const BYTE kDistDirectBits[kDistTableSizeMax] =
|
||||
{
|
||||
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, 17, 17, 18, 18, 19, 19,
|
||||
20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26
|
||||
};
|
||||
|
||||
const UINT32 kNumLenToPosStates = 4;
|
||||
inline UINT32 GetLenToPosState(UINT32 aLen)
|
||||
{
|
||||
aLen -= 2;
|
||||
if (aLen < kNumLenToPosStates)
|
||||
return aLen;
|
||||
return kNumLenToPosStates - 1;
|
||||
}
|
||||
|
||||
const int kMatchMinLen = 2;
|
||||
|
||||
const int kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
|
||||
|
||||
const int kNumAlignBits = 4;
|
||||
const int kAlignTableSize = 1 << kNumAlignBits;
|
||||
const UINT32 kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
const int kStartPosModelIndex = 4;
|
||||
const int kEndPosModelIndex = 14;
|
||||
const int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
const int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
|
||||
const int kMainChoiceLiteralIndex = 0;
|
||||
const int kMainChoiceMatchIndex = 1;
|
||||
|
||||
const int kMatchChoiceDistanceIndex= 0;
|
||||
const int kMatchChoiceRepetitionIndex = 1;
|
||||
|
||||
const int kNumMoveBitsForMainChoice = 5;
|
||||
const int kNumMoveBitsForPosCoders = 5;
|
||||
|
||||
const int kNumMoveBitsForAlignCoders = 5;
|
||||
|
||||
const int kNumMoveBitsForPosSlotCoder = 5;
|
||||
|
||||
const int kNumLitPosStatesBitsEncodingMax = 4;
|
||||
const int kNumLitContextBitsMax = 8;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
299
zsnes/src/jma/lzmadec.cpp
Normal file
299
zsnes/src/jma/lzmadec.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
#include "lzmadec.h"
|
||||
|
||||
#define RETURN_E_OUTOFMEMORY_IF_FALSE(x) { if (!(x)) return E_OUTOFMEMORY; }
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
HRESULT CDecoder::SetDictionarySize(UINT32 aDictionarySize)
|
||||
{
|
||||
if (aDictionarySize > (1 << kDicLogSizeMax))
|
||||
return E_INVALIDARG;
|
||||
|
||||
UINT32 aWindowReservSize = MyMax(aDictionarySize, UINT32(1 << 21));
|
||||
|
||||
if (m_DictionarySize != aDictionarySize)
|
||||
{
|
||||
m_OutWindowStream.Create(aDictionarySize, kMatchMaxLen, aWindowReservSize);
|
||||
m_DictionarySize = aDictionarySize;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetLiteralProperties(
|
||||
UINT32 aLiteralPosStateBits, UINT32 aLiteralContextBits)
|
||||
{
|
||||
if (aLiteralPosStateBits > 8)
|
||||
return E_INVALIDARG;
|
||||
if (aLiteralContextBits > 8)
|
||||
return E_INVALIDARG;
|
||||
m_LiteralDecoder.Create(aLiteralPosStateBits, aLiteralContextBits);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetPosBitsProperties(UINT32 aNumPosStateBits)
|
||||
{
|
||||
if (aNumPosStateBits > NLength::kNumPosStatesBitsMax)
|
||||
return E_INVALIDARG;
|
||||
UINT32 aNumPosStates = 1 << aNumPosStateBits;
|
||||
m_LenDecoder.Create(aNumPosStates);
|
||||
m_RepMatchLenDecoder.Create(aNumPosStates);
|
||||
m_PosStateMask = aNumPosStates - 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_DictionarySize((UINT32)-1)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Create()
|
||||
{
|
||||
for(int i = 0; i < kNumPosModels; i++)
|
||||
{
|
||||
RETURN_E_OUTOFMEMORY_IF_FALSE(
|
||||
m_PosDecoders[i].Create(kDistDirectBits[kStartPosModelIndex + i]));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDecoder::Init(ISequentialInStream *anInStream,
|
||||
ISequentialOutStream *anOutStream)
|
||||
{
|
||||
m_RangeDecoder.Init(anInStream);
|
||||
|
||||
m_OutWindowStream.Init(anOutStream);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < kNumStates; i++)
|
||||
{
|
||||
for (UINT32 j = 0; j <= m_PosStateMask; j++)
|
||||
{
|
||||
m_MainChoiceDecoders[i][j].Init();
|
||||
m_MatchRepShortChoiceDecoders[i][j].Init();
|
||||
}
|
||||
m_MatchChoiceDecoders[i].Init();
|
||||
m_MatchRepChoiceDecoders[i].Init();
|
||||
m_MatchRep1ChoiceDecoders[i].Init();
|
||||
m_MatchRep2ChoiceDecoders[i].Init();
|
||||
}
|
||||
|
||||
m_LiteralDecoder.Init();
|
||||
|
||||
// m_RepMatchLenDecoder.Init();
|
||||
|
||||
for (i = 0; i < kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i].Init();
|
||||
|
||||
for(i = 0; i < kNumPosModels; i++)
|
||||
m_PosDecoders[i].Init();
|
||||
|
||||
m_LenDecoder.Init();
|
||||
m_RepMatchLenDecoder.Init();
|
||||
|
||||
m_PosAlignDecoder.Init();
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CodeReal(ISequentialInStream *anInStream,
|
||||
ISequentialOutStream *anOutStream,
|
||||
const UINT64 *anInSize, const UINT64 *anOutSize)
|
||||
{
|
||||
if (anOutSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
Init(anInStream, anOutStream);
|
||||
|
||||
CState aState;
|
||||
aState.Init();
|
||||
bool aPeviousIsMatch = false;
|
||||
BYTE aPreviousByte = 0;
|
||||
UINT32 aRepDistances[kNumRepDistances];
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
aRepDistances[i] = 0;
|
||||
|
||||
UINT64 aNowPos64 = 0;
|
||||
UINT64 aSize = *anOutSize;
|
||||
while(aNowPos64 < aSize)
|
||||
{
|
||||
UINT64 aNext = MyMin(aNowPos64 + (1 << 18), aSize);
|
||||
while(aNowPos64 < aNext)
|
||||
{
|
||||
UINT32 aPosState = UINT32(aNowPos64) & m_PosStateMask;
|
||||
if (m_MainChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == kMainChoiceLiteralIndex)
|
||||
{
|
||||
// aCounts[0]++;
|
||||
aState.UpdateChar();
|
||||
if(aPeviousIsMatch)
|
||||
{
|
||||
BYTE aMatchByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1);
|
||||
aPreviousByte = m_LiteralDecoder.DecodeWithMatchByte(&m_RangeDecoder,
|
||||
UINT32(aNowPos64), aPreviousByte, aMatchByte);
|
||||
aPeviousIsMatch = false;
|
||||
}
|
||||
else
|
||||
aPreviousByte = m_LiteralDecoder.DecodeNormal(&m_RangeDecoder,
|
||||
UINT32(aNowPos64), aPreviousByte);
|
||||
m_OutWindowStream.PutOneByte(aPreviousByte);
|
||||
aNowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
aPeviousIsMatch = true;
|
||||
UINT32 aDistance, aLen;
|
||||
if(m_MatchChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) ==
|
||||
kMatchChoiceRepetitionIndex)
|
||||
{
|
||||
if(m_MatchRepChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
if(m_MatchRepShortChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
aState.UpdateShortRep();
|
||||
aPreviousByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1);
|
||||
m_OutWindowStream.PutOneByte(aPreviousByte);
|
||||
aNowPos64++;
|
||||
// aCounts[3 + 4]++;
|
||||
continue;
|
||||
}
|
||||
// aCounts[3 + 0]++;
|
||||
aDistance = aRepDistances[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_MatchRep1ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
aDistance = aRepDistances[1];
|
||||
aRepDistances[1] = aRepDistances[0];
|
||||
// aCounts[3 + 1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_MatchRep2ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
// aCounts[3 + 2]++;
|
||||
aDistance = aRepDistances[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// aCounts[3 + 3]++;
|
||||
aDistance = aRepDistances[3];
|
||||
aRepDistances[3] = aRepDistances[2];
|
||||
}
|
||||
aRepDistances[2] = aRepDistances[1];
|
||||
aRepDistances[1] = aRepDistances[0];
|
||||
}
|
||||
aRepDistances[0] = aDistance;
|
||||
}
|
||||
aLen = m_RepMatchLenDecoder.Decode(&m_RangeDecoder, aPosState) + kMatchMinLen;
|
||||
// aCounts[aLen]++;
|
||||
aState.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
aLen = kMatchMinLen + m_LenDecoder.Decode(&m_RangeDecoder, aPosState);
|
||||
aState.UpdateMatch();
|
||||
UINT32 aPosSlot = m_PosSlotDecoder[GetLenToPosState(aLen)].Decode(&m_RangeDecoder);
|
||||
// aCounts[aPosSlot]++;
|
||||
if (aPosSlot >= kStartPosModelIndex)
|
||||
{
|
||||
aDistance = kDistStart[aPosSlot];
|
||||
if (aPosSlot < kEndPosModelIndex)
|
||||
aDistance += m_PosDecoders[aPosSlot - kStartPosModelIndex].Decode(&m_RangeDecoder);
|
||||
else
|
||||
{
|
||||
aDistance += (m_RangeDecoder.DecodeDirectBits(kDistDirectBits[aPosSlot] -
|
||||
kNumAlignBits) << kNumAlignBits);
|
||||
aDistance += m_PosAlignDecoder.Decode(&m_RangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
aDistance = aPosSlot;
|
||||
|
||||
|
||||
aRepDistances[3] = aRepDistances[2];
|
||||
aRepDistances[2] = aRepDistances[1];
|
||||
aRepDistances[1] = aRepDistances[0];
|
||||
|
||||
aRepDistances[0] = aDistance;
|
||||
// UpdateStat(aLen, aPosSlot);
|
||||
}
|
||||
if (aDistance >= aNowPos64)
|
||||
throw E_INVALIDDATA;
|
||||
m_OutWindowStream.CopyBackBlock(aDistance, aLen);
|
||||
aNowPos64 += aLen;
|
||||
aPreviousByte = m_OutWindowStream.GetOneByte(0 - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Flush();
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Code(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize)
|
||||
{
|
||||
try {
|
||||
return CodeReal(anInStream, anOutStream, anInSize, anOutSize);
|
||||
} catch (HRESULT& e) {
|
||||
return e;
|
||||
} catch (...) {
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CDecoder::ReadCoderProperties(ISequentialInStream *anInStream)
|
||||
{
|
||||
UINT32 aNumPosStateBits;
|
||||
UINT32 aLiteralPosStateBits;
|
||||
UINT32 aLiteralContextBits;
|
||||
UINT32 aDictionarySize;
|
||||
|
||||
UINT32 aProcessesedSize;
|
||||
|
||||
BYTE aByte;
|
||||
RETURN_IF_NOT_S_OK(anInStream->Read(&aByte, sizeof(aByte), &aProcessesedSize));
|
||||
if (aProcessesedSize != sizeof(aByte))
|
||||
return E_INVALIDARG;
|
||||
|
||||
aLiteralContextBits = aByte % 9;
|
||||
BYTE aRemainder = aByte / 9;
|
||||
aLiteralPosStateBits = aRemainder % 5;
|
||||
aNumPosStateBits = aRemainder / 5;
|
||||
|
||||
UINT8 uint_buffer[UINT_SIZE];
|
||||
RETURN_IF_NOT_S_OK(anInStream->Read(uint_buffer, sizeof(aDictionarySize), &aProcessesedSize));
|
||||
aDictionarySize = charp_to_uint(uint_buffer);
|
||||
|
||||
if (aProcessesedSize != sizeof(aDictionarySize))
|
||||
return E_INVALIDARG;
|
||||
|
||||
RETURN_IF_NOT_S_OK(SetDictionarySize(aDictionarySize));
|
||||
RETURN_IF_NOT_S_OK(SetLiteralProperties(aLiteralPosStateBits, aLiteralContextBits));
|
||||
RETURN_IF_NOT_S_OK(SetPosBitsProperties(aNumPosStateBits));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
83
zsnes/src/jma/lzmadec.h
Normal file
83
zsnes/src/jma/lzmadec.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LZARITHMETIC_DECODER_H
|
||||
#define __LZARITHMETIC_DECODER_H
|
||||
|
||||
#include "winout.h"
|
||||
#include "lzma.h"
|
||||
#include "lencoder.h"
|
||||
#include "litcoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
typedef CMyBitDecoder<kNumMoveBitsForMainChoice> CMyBitDecoder2;
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
NStream::NWindow::COut m_OutWindowStream;
|
||||
CMyRangeDecoder m_RangeDecoder;
|
||||
|
||||
CMyBitDecoder2 m_MainChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
|
||||
CMyBitDecoder2 m_MatchChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder2 m_MatchRepChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder2 m_MatchRep1ChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder2 m_MatchRep2ChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder2 m_MatchRepShortChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
|
||||
|
||||
CBitTreeDecoder<kNumMoveBitsForPosSlotCoder, kNumPosSlotBits> m_PosSlotDecoder[kNumLenToPosStates];
|
||||
|
||||
CReverseBitTreeDecoder2<kNumMoveBitsForPosCoders> m_PosDecoders[kNumPosModels];
|
||||
CReverseBitTreeDecoder<kNumMoveBitsForAlignCoders, kNumAlignBits> m_PosAlignDecoder;
|
||||
// CBitTreeDecoder2<kNumMoveBitsForPosCoders> m_PosDecoders[kNumPosModels];
|
||||
// CBitTreeDecoder<kNumMoveBitsForAlignCoders, kNumAlignBits> m_PosAlignDecoder;
|
||||
|
||||
NLength::CDecoder m_LenDecoder;
|
||||
NLength::CDecoder m_RepMatchLenDecoder;
|
||||
|
||||
NLiteral::CDecoder m_LiteralDecoder;
|
||||
|
||||
UINT32 m_DictionarySize;
|
||||
|
||||
UINT32 m_PosStateMask;
|
||||
|
||||
HRESULT Create();
|
||||
|
||||
HRESULT Init(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream);
|
||||
|
||||
HRESULT Flush() { return m_OutWindowStream.Flush(); }
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize);
|
||||
|
||||
public:
|
||||
|
||||
CDecoder();
|
||||
|
||||
HRESULT Code(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize);
|
||||
HRESULT ReadCoderProperties(ISequentialInStream *anInStream);
|
||||
|
||||
HRESULT SetDictionarySize(UINT32 aDictionarySize);
|
||||
HRESULT SetLiteralProperties(UINT32 aLiteralPosStateBits, UINT32 aLiteralContextBits);
|
||||
HRESULT SetPosBitsProperties(UINT32 aNumPosStateBits);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
64
zsnes/src/jma/outbyte.cpp
Normal file
64
zsnes/src/jma/outbyte.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "outbyte.h"
|
||||
|
||||
namespace NStream {
|
||||
|
||||
COutByte::COutByte(UINT32 aBufferSize):
|
||||
m_BufferSize(aBufferSize)
|
||||
{
|
||||
m_Buffer = new BYTE[m_BufferSize];
|
||||
}
|
||||
|
||||
COutByte::~COutByte()
|
||||
{
|
||||
delete []m_Buffer;
|
||||
}
|
||||
|
||||
void COutByte::Init(ISequentialOutStream *aStream)
|
||||
{
|
||||
m_Stream = aStream;
|
||||
m_ProcessedSize = 0;
|
||||
m_Pos = 0;
|
||||
}
|
||||
|
||||
HRESULT COutByte::Flush()
|
||||
{
|
||||
if (m_Pos == 0)
|
||||
return S_OK;
|
||||
UINT32 aProcessedSize;
|
||||
HRESULT aResult = m_Stream->Write(m_Buffer, m_Pos, &aProcessedSize);
|
||||
if (aResult != S_OK)
|
||||
return aResult;
|
||||
if (m_Pos != aProcessedSize)
|
||||
return E_FAIL;
|
||||
m_ProcessedSize += aProcessedSize;
|
||||
m_Pos = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void COutByte::WriteBlock()
|
||||
{
|
||||
HRESULT aResult = Flush();
|
||||
if (aResult != S_OK)
|
||||
throw aResult;
|
||||
}
|
||||
|
||||
}
|
||||
61
zsnes/src/jma/outbyte.h
Normal file
61
zsnes/src/jma/outbyte.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_OUTBYTE_H
|
||||
#define __STREAM_OUTBYTE_H
|
||||
|
||||
#include "portable.h"
|
||||
#include "iiostrm.h"
|
||||
|
||||
namespace NStream {
|
||||
|
||||
class COutByte
|
||||
{
|
||||
BYTE *m_Buffer;
|
||||
UINT32 m_Pos;
|
||||
UINT32 m_BufferSize;
|
||||
ISequentialOutStream* m_Stream;
|
||||
UINT64 m_ProcessedSize;
|
||||
|
||||
void WriteBlock();
|
||||
public:
|
||||
COutByte(UINT32 aBufferSize = (1 << 20));
|
||||
~COutByte();
|
||||
|
||||
void Init(ISequentialOutStream *aStream);
|
||||
HRESULT Flush();
|
||||
|
||||
void WriteByte(BYTE aByte)
|
||||
{
|
||||
m_Buffer[m_Pos++] = aByte;
|
||||
if(m_Pos >= m_BufferSize)
|
||||
WriteBlock();
|
||||
}
|
||||
void WriteBytes(const void *aBytes, UINT32 aSize)
|
||||
{
|
||||
for (UINT32 i = 0; i < aSize; i++)
|
||||
WriteByte(((const BYTE *)aBytes)[i]);
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
76
zsnes/src/jma/portable.h
Normal file
76
zsnes/src/jma/portable.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PORTABLE_H
|
||||
#define __PORTABLE_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef long INT32;
|
||||
typedef unsigned long UINT32;
|
||||
typedef long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
|
||||
typedef UINT8 BYTE;
|
||||
typedef UINT16 WORD;
|
||||
typedef UINT32 DWORD;
|
||||
|
||||
typedef unsigned UINT_PTR;
|
||||
|
||||
typedef int BOOL;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define HRESULT int
|
||||
#define S_OK 0
|
||||
#define E_INVALIDARG -1
|
||||
#define E_OUTOFMEMORY -2
|
||||
#define E_FAIL -3
|
||||
#define E_INTERNAL_ERROR -4
|
||||
#define E_INVALIDDATA -5
|
||||
|
||||
template <class T> inline T MyMin(T a, T b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
template <class T> inline T MyMax(T a, T b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
#define RETURN_IF_NOT_S_OK(x) { HRESULT __aResult_ = (x); if(__aResult_ != S_OK) return __aResult_; }
|
||||
|
||||
|
||||
#define UINT_SIZE (4)
|
||||
|
||||
//Convert an array of 4 bytes back into an integer
|
||||
inline unsigned int charp_to_uint(const unsigned char buffer[UINT_SIZE])
|
||||
{
|
||||
unsigned int num = (unsigned int)buffer[3];
|
||||
num |= ((unsigned int)buffer[2]) << 8;
|
||||
num |= ((unsigned int)buffer[1]) << 16;
|
||||
num |= ((unsigned int)buffer[0]) << 24;
|
||||
return(num);
|
||||
}
|
||||
|
||||
#endif
|
||||
61
zsnes/src/jma/rcdefs.h
Normal file
61
zsnes/src/jma/rcdefs.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __RCDEFS_H
|
||||
#define __RCDEFS_H
|
||||
|
||||
#include "aribitcd.h"
|
||||
#include "ariconst.h"
|
||||
|
||||
#define RC_INIT_VAR \
|
||||
UINT32 aRange = aRangeDecoder->m_Range; \
|
||||
UINT32 aCode = aRangeDecoder->m_Code;
|
||||
|
||||
#define RC_FLUSH_VAR \
|
||||
aRangeDecoder->m_Range = aRange; \
|
||||
aRangeDecoder->m_Code = aCode;
|
||||
|
||||
#define RC_NORMALIZE \
|
||||
if (aRange < NCompression::NArithmetic::kTopValue) \
|
||||
{ \
|
||||
aCode = (aCode << 8) | aRangeDecoder->m_Stream.ReadByte(); \
|
||||
aRange <<= 8; }
|
||||
|
||||
#define RC_GETBIT2(aNumMoveBits, aProb, aModelIndex, Action0, Action1) \
|
||||
{UINT32 aNewBound = (aRange >> NCompression::NArithmetic::kNumBitModelTotalBits) * aProb; \
|
||||
if (aCode < aNewBound) \
|
||||
{ \
|
||||
Action0; \
|
||||
aRange = aNewBound; \
|
||||
aProb += (NCompression::NArithmetic::kBitModelTotal - aProb) >> aNumMoveBits; \
|
||||
aModelIndex <<= 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Action1; \
|
||||
aRange -= aNewBound; \
|
||||
aCode -= aNewBound; \
|
||||
aProb -= (aProb) >> aNumMoveBits; \
|
||||
aModelIndex = (aModelIndex << 1) + 1; \
|
||||
}} \
|
||||
RC_NORMALIZE
|
||||
|
||||
#define RC_GETBIT(aNumMoveBits, aProb, aModelIndex) RC_GETBIT2(aNumMoveBits, aProb, aModelIndex, ; , ;)
|
||||
|
||||
#endif
|
||||
251
zsnes/src/jma/rngcoder.h
Normal file
251
zsnes/src/jma/rngcoder.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __COMPRESSION_RANGECODER_H
|
||||
#define __COMPRESSION_RANGECODER_H
|
||||
|
||||
#include "inbyte.h"
|
||||
#include "outbyte.h"
|
||||
|
||||
namespace NCompression {
|
||||
namespace NArithmetic {
|
||||
|
||||
const UINT32 kNumTopBits = 24;
|
||||
const UINT32 kTopValue = (1 << kNumTopBits);
|
||||
|
||||
class CRangeEncoder
|
||||
{
|
||||
NStream::COutByte m_Stream;
|
||||
UINT64 m_Low;
|
||||
UINT32 m_Range;
|
||||
UINT32 m_FFNum;
|
||||
BYTE m_Cache;
|
||||
|
||||
public:
|
||||
void Init(ISequentialOutStream *aStream)
|
||||
{
|
||||
m_Stream.Init(aStream);
|
||||
m_Low = 0;
|
||||
m_Range = UINT32(-1);
|
||||
m_FFNum = 0;
|
||||
m_Cache = 0;
|
||||
}
|
||||
|
||||
void FlushData()
|
||||
{
|
||||
// m_Low += 1;
|
||||
for(int i = 0; i < 5; i++)
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
HRESULT FlushStream()
|
||||
{ return m_Stream.Flush(); }
|
||||
|
||||
void Encode(UINT32 aStart, UINT32 aSize, UINT32 aTotal)
|
||||
{
|
||||
m_Low += aStart * (m_Range /= aTotal);
|
||||
m_Range *= aSize;
|
||||
while (m_Range < kTopValue)
|
||||
{
|
||||
m_Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void EncodeDirectBitsDiv(UINT32 aValue, UINT32 aNumTotalBits)
|
||||
{
|
||||
m_Low += aValue * (m_Range >>= aNumTotalBits);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void EncodeDirectBitsDiv2(UINT32 aValue, UINT32 aNumTotalBits)
|
||||
{
|
||||
if (aNumTotalBits <= kNumBottomBits)
|
||||
EncodeDirectBitsDiv(aValue, aNumTotalBits);
|
||||
else
|
||||
{
|
||||
EncodeDirectBitsDiv(aValue >> kNumBottomBits, (aNumTotalBits - kNumBottomBits));
|
||||
EncodeDirectBitsDiv(aValue & ((1 << kBottomValueBits) - 1), kNumBottomBits);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void ShiftLow()
|
||||
{
|
||||
if (m_Low < (UINT32)0xFF000000 || UINT32(m_Low >> 32) == 1)
|
||||
{
|
||||
m_Stream.WriteByte(m_Cache + BYTE(m_Low >> 32));
|
||||
for (;m_FFNum != 0; m_FFNum--)
|
||||
m_Stream.WriteByte(0xFF + BYTE(m_Low >> 32));
|
||||
m_Cache = BYTE(UINT32(m_Low) >> 24);
|
||||
}
|
||||
else
|
||||
m_FFNum++;
|
||||
m_Low = UINT32(m_Low) << 8;
|
||||
}
|
||||
|
||||
void EncodeDirectBits(UINT32 aValue, UINT32 aNumTotalBits)
|
||||
{
|
||||
for (int i = aNumTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
m_Range >>= 1;
|
||||
if (((aValue >> i) & 1) == 1)
|
||||
m_Low += m_Range;
|
||||
if (m_Range < kTopValue)
|
||||
{
|
||||
m_Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeBit(UINT32 aSize0, UINT32 aNumTotalBits, UINT32 aSymbol)
|
||||
{
|
||||
UINT32 aNewBound = (m_Range >> aNumTotalBits) * aSize0;
|
||||
if (aSymbol == 0)
|
||||
m_Range = aNewBound;
|
||||
else
|
||||
{
|
||||
m_Low += aNewBound;
|
||||
m_Range -= aNewBound;
|
||||
}
|
||||
while (m_Range < kTopValue)
|
||||
{
|
||||
m_Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() { return m_Stream.GetProcessedSize() + m_FFNum; }
|
||||
};
|
||||
|
||||
class CRangeDecoder
|
||||
{
|
||||
public:
|
||||
NStream::CInByte m_Stream;
|
||||
UINT32 m_Range;
|
||||
UINT32 m_Code;
|
||||
UINT32 m_Word;
|
||||
void Normalize()
|
||||
{
|
||||
while (m_Range < kTopValue)
|
||||
{
|
||||
m_Code = (m_Code << 8) | m_Stream.ReadByte();
|
||||
m_Range <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void Init(ISequentialInStream *aStream)
|
||||
{
|
||||
m_Stream.Init(aStream);
|
||||
m_Code = 0;
|
||||
m_Range = UINT32(-1);
|
||||
for(int i = 0; i < 5; i++)
|
||||
m_Code = (m_Code << 8) | m_Stream.ReadByte();
|
||||
}
|
||||
|
||||
UINT32 GetThreshold(UINT32 aTotal)
|
||||
{
|
||||
return (m_Code) / ( m_Range /= aTotal);
|
||||
}
|
||||
|
||||
void Decode(UINT32 aStart, UINT32 aSize, UINT32 aTotal)
|
||||
{
|
||||
m_Code -= aStart * m_Range;
|
||||
m_Range *= aSize;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
/*
|
||||
UINT32 DecodeDirectBitsDiv(UINT32 aNumTotalBits)
|
||||
{
|
||||
m_Range >>= aNumTotalBits;
|
||||
UINT32 aThreshold = m_Code / m_Range;
|
||||
m_Code -= aThreshold * m_Range;
|
||||
|
||||
Normalize();
|
||||
return aThreshold;
|
||||
}
|
||||
|
||||
UINT32 DecodeDirectBitsDiv2(UINT32 aNumTotalBits)
|
||||
{
|
||||
if (aNumTotalBits <= kNumBottomBits)
|
||||
return DecodeDirectBitsDiv(aNumTotalBits);
|
||||
UINT32 aResult = DecodeDirectBitsDiv(aNumTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
return (aResult | DecodeDirectBitsDiv(kNumBottomBits));
|
||||
}
|
||||
*/
|
||||
|
||||
UINT32 DecodeDirectBits(UINT32 aNumTotalBits)
|
||||
{
|
||||
UINT32 aRange = m_Range;
|
||||
UINT32 aCode = m_Code;
|
||||
UINT32 aResult = 0;
|
||||
for (UINT32 i = aNumTotalBits; i > 0; i--)
|
||||
{
|
||||
aRange >>= 1;
|
||||
/*
|
||||
aResult <<= 1;
|
||||
if (aCode >= aRange)
|
||||
{
|
||||
aCode -= aRange;
|
||||
aResult |= 1;
|
||||
}
|
||||
*/
|
||||
UINT32 t = (aCode - aRange) >> 31;
|
||||
aCode -= aRange & (t - 1);
|
||||
// aRange = aRangeTmp + ((aRange & 1) & (1 - t));
|
||||
aResult = (aResult << 1) | (1 - t);
|
||||
|
||||
if (aRange < kTopValue)
|
||||
{
|
||||
aCode = (aCode << 8) | m_Stream.ReadByte();
|
||||
aRange <<= 8;
|
||||
}
|
||||
}
|
||||
m_Range = aRange;
|
||||
m_Code = aCode;
|
||||
return aResult;
|
||||
}
|
||||
|
||||
UINT32 DecodeBit(UINT32 aSize0, UINT32 aNumTotalBits)
|
||||
{
|
||||
UINT32 aNewBound = (m_Range >> aNumTotalBits) * aSize0;
|
||||
UINT32 aSymbol;
|
||||
if (m_Code < aNewBound)
|
||||
{
|
||||
aSymbol = 0;
|
||||
m_Range = aNewBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
aSymbol = 1;
|
||||
m_Code -= aNewBound;
|
||||
m_Range -= aNewBound;
|
||||
}
|
||||
Normalize();
|
||||
return aSymbol;
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() {return m_Stream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
90
zsnes/src/jma/winout.cpp
Normal file
90
zsnes/src/jma/winout.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "winout.h"
|
||||
|
||||
namespace NStream {
|
||||
namespace NWindow {
|
||||
|
||||
void COut::Create(UINT32 aKeepSizeBefore, UINT32 aKeepSizeAfter, UINT32 aKeepSizeReserv)
|
||||
{
|
||||
m_Pos = 0;
|
||||
m_PosLimit = aKeepSizeReserv + aKeepSizeBefore;
|
||||
m_KeepSizeBefore = aKeepSizeBefore;
|
||||
m_KeepSizeAfter = aKeepSizeAfter;
|
||||
m_KeepSizeReserv = aKeepSizeReserv;
|
||||
m_StreamPos = 0;
|
||||
m_MoveFrom = m_KeepSizeReserv;
|
||||
m_WindowSize = aKeepSizeBefore;
|
||||
UINT32 aBlockSize = m_KeepSizeBefore + m_KeepSizeAfter + m_KeepSizeReserv;
|
||||
delete []m_Buffer;
|
||||
m_Buffer = new BYTE[aBlockSize];
|
||||
}
|
||||
|
||||
COut::~COut()
|
||||
{
|
||||
delete []m_Buffer;
|
||||
}
|
||||
|
||||
void COut::SetWindowSize(UINT32 aWindowSize)
|
||||
{
|
||||
m_WindowSize = aWindowSize;
|
||||
m_MoveFrom = m_KeepSizeReserv + m_KeepSizeBefore - aWindowSize;
|
||||
}
|
||||
|
||||
void COut::Init(ISequentialOutStream *aStream, bool aSolid)
|
||||
{
|
||||
m_Stream = aStream;
|
||||
|
||||
if(aSolid)
|
||||
m_StreamPos = m_Pos;
|
||||
else
|
||||
{
|
||||
m_Pos = 0;
|
||||
m_PosLimit = m_KeepSizeReserv + m_KeepSizeBefore;
|
||||
m_StreamPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT COut::Flush()
|
||||
{
|
||||
UINT32 aSize = m_Pos - m_StreamPos;
|
||||
if(aSize == 0)
|
||||
return S_OK;
|
||||
UINT32 aProcessedSize;
|
||||
HRESULT aResult = m_Stream->Write(m_Buffer + m_StreamPos, aSize, &aProcessedSize);
|
||||
if (aResult != S_OK)
|
||||
return aResult;
|
||||
if (aSize != aProcessedSize)
|
||||
return E_FAIL;
|
||||
m_StreamPos = m_Pos;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void COut::MoveBlockBackward()
|
||||
{
|
||||
HRESULT aResult = Flush();
|
||||
if (aResult != S_OK)
|
||||
throw aResult;
|
||||
memmove(m_Buffer, m_Buffer + m_MoveFrom, m_WindowSize + m_KeepSizeAfter);
|
||||
m_Pos -= m_MoveFrom;
|
||||
m_StreamPos -= m_MoveFrom;
|
||||
}
|
||||
|
||||
}}
|
||||
90
zsnes/src/jma/winout.h
Normal file
90
zsnes/src/jma/winout.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
|
||||
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_WINDOWOUT_H
|
||||
#define __STREAM_WINDOWOUT_H
|
||||
|
||||
#include "iiostrm.h"
|
||||
|
||||
namespace NStream {
|
||||
namespace NWindow {
|
||||
|
||||
// m_KeepSizeBefore: how mach BYTEs must be in buffer before m_Pos;
|
||||
// m_KeepSizeAfter: how mach BYTEs must be in buffer after m_Pos;
|
||||
// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
|
||||
// must be >= aKeepSizeAfter; // test it
|
||||
|
||||
class COut
|
||||
{
|
||||
BYTE *m_Buffer;
|
||||
UINT32 m_Pos;
|
||||
UINT32 m_PosLimit;
|
||||
UINT32 m_KeepSizeBefore;
|
||||
UINT32 m_KeepSizeAfter;
|
||||
UINT32 m_KeepSizeReserv;
|
||||
UINT32 m_StreamPos;
|
||||
|
||||
UINT32 m_WindowSize;
|
||||
UINT32 m_MoveFrom;
|
||||
|
||||
ISequentialOutStream *m_Stream;
|
||||
|
||||
virtual void MoveBlockBackward();
|
||||
public:
|
||||
COut(): m_Buffer(0), m_Stream(0) {}
|
||||
virtual ~COut();
|
||||
void Create(UINT32 aKeepSizeBefore,
|
||||
UINT32 aKeepSizeAfter, UINT32 aKeepSizeReserv = (1<<17));
|
||||
void SetWindowSize(UINT32 aWindowSize);
|
||||
|
||||
void Init(ISequentialOutStream *aStream, bool aSolid = false);
|
||||
HRESULT Flush();
|
||||
|
||||
UINT32 GetCurPos() const { return m_Pos; }
|
||||
const BYTE *GetPointerToCurrentPos() const { return m_Buffer + m_Pos;};
|
||||
|
||||
void CopyBackBlock(UINT32 aDistance, UINT32 aLen)
|
||||
{
|
||||
if (m_Pos >= m_PosLimit)
|
||||
MoveBlockBackward();
|
||||
BYTE *p = m_Buffer + m_Pos;
|
||||
aDistance++;
|
||||
for(UINT32 i = 0; i < aLen; i++)
|
||||
p[i] = p[i - aDistance];
|
||||
m_Pos += aLen;
|
||||
}
|
||||
|
||||
void PutOneByte(BYTE aByte)
|
||||
{
|
||||
if (m_Pos >= m_PosLimit)
|
||||
MoveBlockBackward();
|
||||
m_Buffer[m_Pos++] = aByte;
|
||||
}
|
||||
|
||||
BYTE GetOneByte(UINT32 anIndex) const
|
||||
{
|
||||
return m_Buffer[m_Pos + anIndex];
|
||||
}
|
||||
|
||||
BYTE *GetBuffer() const { return m_Buffer; }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
64
zsnes/src/jma/zsnesjma.cpp
Normal file
64
zsnes/src/jma/zsnesjma.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "zsnesjma.h"
|
||||
#include "jma.h"
|
||||
|
||||
extern unsigned char *romdata;
|
||||
extern unsigned int curromspace;
|
||||
extern unsigned int maxromspace;
|
||||
|
||||
void load_jma_file(const char *filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
JMA::jma_open JMAFile(filename);
|
||||
vector<JMA::jma_public_file_info> file_info = JMAFile.get_files_info();
|
||||
|
||||
string our_file_name;
|
||||
size_t our_file_size = 0;
|
||||
|
||||
for (vector<JMA::jma_public_file_info>::iterator i = file_info.begin(); i != file_info.end(); i++)
|
||||
{
|
||||
//Check for valid ROM based on size
|
||||
if ((i->size <= maxromspace+512) && (i->size > our_file_size))
|
||||
{
|
||||
our_file_name = i->name;
|
||||
our_file_size = i->size;
|
||||
}
|
||||
}
|
||||
|
||||
if (!our_file_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JMAFile.extract_file(our_file_name, romdata);
|
||||
|
||||
curromspace = our_file_size;
|
||||
}
|
||||
catch (JMA::jma_errors jma_error)
|
||||
{
|
||||
//No need to do anything
|
||||
}
|
||||
}
|
||||
|
||||
27
zsnes/src/jma/zsnesjma.h
Normal file
27
zsnes/src/jma/zsnesjma.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com )
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void load_jma_file(const char *filename);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user