: This reimplementation is not backward-compatible. (Read UPDATE)
UPDATE: Earlier, I had determined the original implementation to be in error, in the assumption of certain function specification, hence the writing of this page with the intention to supposedly correct the original program. I have changed my view and redetermined that the original implementation is not broken, because previously I made wrong deduction on its sector-detection function, initially believing that it might produce false positives and false negatives, and potentially data loss and data corruption. With that being said, this reimplementation should now be considered as a program that is different from the original program and no longer as a correction, and there is now room for backward compatibility.
0.
This algorithm compresses the Red Book-conformant CD formats (Mode 1,
Mode 2 Form 1, Mode 2 Form 2). It strips off the EDC/ECC of the sectors at compression, and it reconstructs the EDC/ECC at decompression. Any
original incorrect EDC/ECC (such as the case in copy-protection scheme)
(which cannot be faithfully reconstructed as it is in the original disk)
is skipped. This compression algorithm is only for CD files with
2,352-byte-sized sectors.
1. In Mode 2 Form 1 and Form
2, the 3-byte address (byte 0xC - 0xE) is saved.
2. This reimplementation
. (I might rewrite this program)
3. This reimplementation requires CD files to be in size of multiples of 2,352 bytes.
4. This implementation has different sector-detection function. This program detects Mode 2 (Form 1 and Form 2) with the 16-byte headers, meanwhile the original program detects Mode 2 (Form 1 and Form 2) without the 16-byte headers.
: Data, to be saved and retrieved later for decompression.
: Data, to be checked and discarded, to be reconstructed at decompression.
1. Determine the properties of the blocks in the sector.
2. Test, whether the EDC/ECC can be reconstructed.
Sample #1: Files with Mode 1 sectors, Mode 2 Form 1 sectors (sans 16-byte headers), and literal bytes
a. This reimplementation, samples: (Your mileage may vary - Sample #1 does not have standard Mode 2 Form 1 sectors)
b. Original implementation, samples: (Sample #1 has Mode 2 Form 1 sectors
/*Bloody C99 keywords, I deny!*/
#include<stdint.h>
typedef uint8_t t1u;
typedef int8_t t1s;
typedef uint16_t t2u;
typedef int16_t t2s;
typedef uint32_t t4u;
typedef int32_t t4s;typedef float t4f;
typedef uint64_t t8u;
typedef int64_t t8s;typedef double t8f;
typedef char t1c;
/*Haters gonna hate ... */
typedef void v;
typedef t4u tHr;
#define ig else if
#define ih else
#define rK noexcept
#define rU const noexcept
#define rL throw(tHr)
#define rV const throw(tHr)
#define rY (*this)
#define r__e break;case
#include<cmath>
#define eCG
#define eA8
inline t2u xW(t2u p)rK{return(t2u)((t2u)(p<<8)|(t2u)(p>>8));}
inline t4u xW(t4u p)rK{return((p&0x000000FFU)<<24)|((p&0x0000FF00U)<<8)|((p&0x00FF0000U)>>8)|((p&0xFF000000U)>>24);}
inline t8u xW(t8u p)rK{p=
(p&0x00000000FFFFFFFF)<<0x20|(p&0xFFFFFFFF00000000ULL)>>0x20;p=
(p&0x0000FFFF0000FFFF)<<0x10|(p&0xFFFF0000FFFF0000ULL)>>0x10;return
(p&0x00FF00FF00FF00FF)<<0x08|(p&0xFF00FF00FF00FF00ULL)>>0x08;}
#ifdef eAEB
inline t2u xWL(t2u p)rK{return xW(p);}inline t2u xWB(t2u p)rK{return p;}
inline t4u xWL(t4u p)rK{return xW(p);}inline t4u xWB(t4u p)rK{return p;}
inline t8u xWL(t8u p)rK{return xW(p);}inline t8u xWB(t8u p)rK{return p;}
#else
inline t2u xWL(t2u p)rK{return p;}inline t2u xWB(t2u p)rK{return xW(p);}
inline t4u xWL(t4u p)rK{return p;}inline t4u xWB(t4u p)rK{return xW(p);}
inline t8u xWL(t8u p)rK{return p;}inline t8u xWB(t8u p)rK{return xW(p);}
#endif
#ifdef eCG
#ifdef eA8
#define oP8 "lu"
#else
#define oP8 "llu"
#endif
#elif defined eCV
#define oP8 "I64"
#else
#define oP8 "llu"
#endif
#include<fstream>
struct tFi{private:mutable FILE*mh;public:
tFi&operator=(tFi const&)rK=default;tFi&operator=(tFi&&)rK=default;
tFi(tFi const&)rK=default;tFi(tFi&&)rK=default;tFi()rK=default;
typedef t8u tL;
v ARB_h(t1c const*)rL;
v AWB_h(t1c const*)rL;
inline v B()rK{fclose(mh);}
t4u kRd(v*,t4u)rU;
t4u kRi(v const*,t4u)rU;
bool kbRd(v*,t4u)rU;
bool kbRi(v const*,t4u)rU;
v uRd_h(v*,t4u)rV;
v uRi_h(v const*,t4u)rV;
v uSkSt_h(tL)rV;
v uSkCr_h(tL)rV;
v uSkBF_h(tL)rV;
tL kTl_h()rV;
tL kLh_h()rV;
v uK_h(t1u)rV;
t1u kK_h()rV;};
#ifdef eCV
#define fFO(p,A,F)fopen_s(&p,A,F)
#else
#define fFO(p,A,F)p=fopen(A,F)
#endif
v tFi::ARB_h(t1c const*p)rL{fFO(mh,p,"rb");if(!mh){throw(tHr)0;}}
v tFi::AWB_h(t1c const*p)rL{fFO(mh,p,"wb");if(!mh){throw(tHr)0;}}
v tFi::uK_h(t1u p)rV{if(fputc(p,mh)==EOF){throw(tHr)0;}}
t1u tFi::kK_h()rV{t4s l=fgetc(mh);if(l==EOF){throw(tHr)0;}return(t1u)l;}
t4u tFi::kRd(v*p,t4u q)rU{return fread(p,1,q,mh);}
t4u tFi::kRi(v const*p,t4u q)rU{return fwrite(p,1,q,mh);}
bool tFi::kbRd(v*p,t4u q)rU{return kRd(p,q)==q;}
bool tFi::kbRi(v const*p,t4u q)rU{return kRi(p,q)==q;}
v tFi::uRd_h(v*p,t4u q)rV{if(kRd(p,q)!=q){throw;}}
v tFi::uRi_h(v const*p,t4u q)rV{if(kRi(p,q)!=q){throw;}}
v tFi::uSkSt_h(tL p)rV{if(fseek(mh,(t8u)p,SEEK_SET)){throw(tHr)0;}}
v tFi::uSkCr_h(tL p)rV{if(fseek(mh,(t8u)p,SEEK_CUR)){throw(tHr)0;}}
v tFi::uSkBF_h(tL p)rV{if(fseek(mh,(t8u)p,SEEK_END)){throw(tHr)0;}}
tFi::tL tFi::kTl_h()rV{t8s l=ftell(mh);if(l==-1L){throw(tHr)0;}return(tL)(t8u)l;}
tFi::tL tFi::kLh_h()rV{tL l;try{uSkBF_h((tL)0),l=kTl_h();}catch(tHr){throw;}return l;}
struct __tS{public:
static t1u const cECCF[0x100];
static t1u const cECCB[0x100];
static t4u const cEDC[0x100];
private:t1u m[0x930];
static t4u pxEDC(t4u,t1u const*,t4u)rK;
static t4u pxEDC(t4u const*,t4u)rK;
static v pwPQ_(t1u const*,t1u*,t4u,t4u,t4u,t4u)rK;static bool pxbPQ_(t1u const*,t1u const*,t4u,t4u,t4u,t4u)rK;
static v pwPQ0(t1u const*,t1u*,t4u,t4u,t4u,t4u)rK;static bool pxbPQ0(t1u const*,t1u const*,t4u,t4u,t4u,t4u)rK;
v puECC__()rK;bool pkbECC__()rU;
v puECC0_()rK;bool pkbECC0_()rU;
v puEDC1_()rK;bool pkbEDC1_()rU;
v puEDC21()rK;bool pkbEDC21()rU;
v puEDC22()rK;bool pkbEDC22()rU;
public:
inline t4u&operator()(t4u p)rK{return((t4u*)this)[p];}inline t4u const&operator()(t4u p)rU{return((t4u*)this)[p];}
inline t4u kEDC(t4u p)rU{return pxEDC(p,(t1u const*)this,0x930);}
t1u kT()rU;
t4u kM0_(tFi const&,t4u)rL;
t4u kM1_(tFi const&,t4u)rL;
t4u kM21(tFi const&,t4u)rL;
t4u kM22(tFi const&,t4u)rK;};
t4u __tS::pxEDC(t4u p,t1u const*q,t4u Z)rK{while(Z--){p=(p>>8)^cEDC[(p^(*q++))&0xFF];}return p;}
t4u __tS::pxEDC(t4u const*p,t4u q)rK{return pxEDC(0,(t1u const*)p,q<<2);}
v __tS::pwPQ_(t1u const*p,t1u*D,t4u pMN,t4u pNN,t4u pMM,t4u pNI)rK{t4u Z=pMN*pNN;for(t4u i=0;i<pMN;++i){t4u I=(i>>1)*pMM+(i&1);t1u A=0,B=0;
t4u j=pNN;while(j--){t1u T=p[I];
I+=pNI;if(I>=Z){I-=Z;}A^=T;B^=T;A=cECCF[A];}A=cECCB[cECCF[A]^B];D[i]=A,D[i+pMN]=A^B;}}
v __tS::pwPQ0(t1u const*p,t1u*D,t4u pMN,t4u pNN,t4u pMM,t4u pNI)rK{t4u Z=pMN*pNN;for(t4u i=0;i<pMN;++i){t4u I=(i>>1)*pMM+(i&1);t1u A=0,B=0;
t4u j=pNN;while(j--){t1u T;if(I<4){T=0;}ih{T=p[I];}
I+=pNI;if(I>=Z){I-=Z;}A^=T;B^=T;A=cECCF[A];}A=cECCB[cECCF[A]^B];D[i]=A,D[i+pMN]=A^B;}}
bool __tS::pxbPQ_(t1u const*p,t1u const*D,t4u pMN,t4u pNN,t4u pMM,t4u pNI)rK{t4u Z=pMN*pNN;for(t4u i=0;i<pMN;++i){t4u I=(i>>1)*pMM+(i&1);t1u A=0,B=0;
t4u j=pNN;while(j--){t1u T=p[I];
I+=pNI;if(I>=Z){I-=Z;}A^=T;B^=T;A=cECCF[A];}A=cECCB[cECCF[A]^B];if(D[i]!=A||D[i+pMN]!=(A^B)){return 0;}}return 1;}
bool __tS::pxbPQ0(t1u const*p,t1u const*D,t4u pMN,t4u pNN,t4u pMM,t4u pNI)rK{t4u Z=pMN*pNN;for(t4u i=0;i<pMN;++i){t4u I=(i>>1)*pMM+(i&1);t1u A=0,B=0;
t4u j=pNN;while(j--){t1u T;if(I<4){T=0;}ih{T=p[I];}
I+=pNI;if(I>=Z){I-=Z;}A^=T;B^=T;A=cECCF[A];}A=cECCB[cECCF[A]^B];if(D[i]!=A||D[i+pMN]!=(A^B)){return 0;}}return 1;}
bool __tS::pkbECC__()rU{return pxbPQ_((t1u const*)&rY(3),(t1u const*)&rY(0x207),0x56,0x18,0x02,0x56)&&pxbPQ_((t1u const*)&rY(3),(t1u const*)&rY(0x232),0x34,0x2B,0x56,0x58);}
bool __tS::pkbECC0_()rU{return pxbPQ0((t1u const*)&rY(3),(t1u const*)&rY(0x207),0x56,0x18,0x02,0x56)&&pxbPQ0((t1u const*)&rY(3),(t1u const*)&rY(0x232),0x34,0x2B,0x56,0x58);}
v __tS::puECC__()rK{pwPQ_((t1u const*)&rY(3),(t1u*)&rY(0x207),0x56,0x18,0x02,0x56),pwPQ_((t1u const*)&rY(3),(t1u*)&rY(0x232),0x34,0x2B,0x56,0x58);}
v __tS::puECC0_()rK{pwPQ0((t1u const*)&rY(3),(t1u*)&rY(0x207),0x56,0x18,0x02,0x56),pwPQ0((t1u const*)&rY(3),(t1u*)&rY(0x232),0x34,0x2B,0x56,0x58);}
v __tS::puEDC1_()rK{rY(0x204)=xWL(pxEDC(&rY(0),0x204));}bool __tS::pkbEDC1_()rU{return rY(0x204)==xWL(pxEDC(&rY(0),0x204));}
v __tS::puEDC21()rK{rY(0x206)=xWL(pxEDC(&rY(4),0x202));}bool __tS::pkbEDC21()rU{return rY(0x206)==xWL(pxEDC(&rY(4),0x202));}
v __tS::puEDC22()rK{rY(0x24B)=xWL(pxEDC(&rY(4),0x247));}bool __tS::pkbEDC22()rU{return rY(0x24B)==xWL(pxEDC(&rY(4),0x247));}
t1u __tS::kT()rU{
if(rY(0)==xWB((t4u)0x00FFFFFFU)&&rY(1)==0xFFFFFFFFU&&rY(2)==xWB((t4u)0xFFFFFF00U)){
if(*(0xF+(t1u const*)this)==1){
if(!rY(0x205)&&!rY(0x206)){/*Is Mode 1*/
if(pkbEDC1_()&&pkbECC__()){return 1;}/*Can reproduce EDC/ECC*/
/*Seems to be Mode 1,but cannot reproduce EDC/ECC*/}}
ig(*(0xF+(t1u const*)this)==2){
if(rY(4)==rY(5)){/*Is Mode 2*/
if(pkbEDC21()&&pkbECC0_()){return 2;}/*Can reproduce EDC/ECC of Mode 2 Form 1*/
ig(pkbEDC22()){return 3;}/*Can reproduce EDC of Mode 2 Form 2, apparently cannot reproduce EDC/ECC of Mode 1 Form 1*/
/*Cannot reproduce EDC/ECC Mode 2 Form 1, cannot reproduce EDC of Mode 2 Form 2*/}}}return 0;}
t4u __tS::kM0_(tFi const&p,t4u const q)rL{
if(!p.kbRd(&rY(0),0x0930)){printf("#0 Read#1 fail: Cannot read data!\n");throw(tHr)0;}
return kEDC(q);}
t4u __tS::kM1_(tFi const&p,t4u const q)rL{
rY(0)=xWB((t4u)0x00FFFFFF),rY(1)=0xFFFFFFFF,
rY(2)=xWB((t4u)0xFFFFFF00),rY(3)=xWB((t4u)0x00000001);
if(!p.kbRd(&rY(3),0x003)){printf("#1 Read#1 fail: Cannot read address!\n");throw(tHr)0;}
if(!p.kbRd(&rY(4),0x800)){printf("#1 Read#2 fail: Cannot read data!\n");throw(tHr)0;}
rY(0x205)=rY(0x206)=0,puEDC1_(),puECC__();return kEDC(q);}
t4u __tS::kM21(tFi const&p,t4u const q)rL{
rY(0)=xWB((t4u)0x00FFFFFF),rY(1)=0xFFFFFFFF,
rY(2)=xWB((t4u)0xFFFFFF00),rY(3)=xWB((t4u)0x00000002);
if(!p.kbRd(&rY(3),0x003)){printf("#2 Read#1 fail: Cannot read address!\n");throw(tHr)0;}
if(!p.kbRd(&rY(5),0x804)){printf("#2 Read#2 fail: Cannot read data!\n");throw(tHr)0;}
rY(4)=rY(5),puEDC21(),puECC0_();return kEDC(q);}
t4u __tS::kM22(tFi const&p,t4u const q)rK{
rY(0)=xWB((t4u)0x00FFFFFF),rY(1)=0xFFFFFFFF,
rY(2)=xWB((t4u)0xFFFFFF00),rY(3)=xWB((t4u)0x00000002);
if(!p.kbRd(&rY(3),0x003)){printf("#3 Read#1 fail: Cannot read address!\n");throw(tHr)0;}
if(!p.kbRd(&rY(5),0x918)){printf("#3 Read#2 fail: Cannot read data!\n");throw(tHr)0;}
rY(4)=rY(5),puEDC22();return kEDC(q);}
t1u const __tS::cECCF[0x100]={
0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,0x32,0x34,0x36,0x38,0x3A,0x3C,0x3E,0x40,0x42,0x44,0x46,0x48,0x4A,0x4C,0x4E,0x50,0x52,0x54,0x56,0x58,0x5A,0x5C,0x5E,0x60,0x62,0x64,0x66,0x68,0x6A,0x6C,0x6E,0x70,0x72,0x74,0x76,0x78,0x7A,0x7C,0x7E,0x80,0x82,0x84,0x86,0x88,0x8A,0x8C,0x8E,0x90,0x92,0x94,0x96,0x98,0x9A,0x9C,0x9E,0xA0,0xA2,0xA4,0xA6,0xA8,0xAA,0xAC,0xAE,0xB0,0xB2,0xB4,0xB6,0xB8,0xBA,0xBC,0xBE,0xC0,0xC2,0xC4,0xC6,0xC8,0xCA,0xCC,0xCE,0xD0,0xD2,0xD4,0xD6,0xD8,0xDA,0xDC,0xDE,0xE0,0xE2,0xE4,0xE6,0xE8,0xEA,0xEC,0xEE,0xF0,0xF2,0xF4,0xF6,0xF8,0xFA,0xFC,0xFE,
0x1D,0x1F,0x19,0x1B,0x15,0x17,0x11,0x13,0x0D,0x0F,0x09,0x0B,0x05,0x07,0x01,0x03,0x3D,0x3F,0x39,0x3B,0x35,0x37,0x31,0x33,0x2D,0x2F,0x29,0x2B,0x25,0x27,0x21,0x23,0x5D,0x5F,0x59,0x5B,0x55,0x57,0x51,0x53,0x4D,0x4F,0x49,0x4B,0x45,0x47,0x41,0x43,0x7D,0x7F,0x79,0x7B,0x75,0x77,0x71,0x73,0x6D,0x6F,0x69,0x6B,0x65,0x67,0x61,0x63,0x9D,0x9F,0x99,0x9B,0x95,0x97,0x91,0x93,0x8D,0x8F,0x89,0x8B,0x85,0x87,0x81,0x83,0xBD,0xBF,0xB9,0xBB,0xB5,0xB7,0xB1,0xB3,0xAD,0xAF,0xA9,0xAB,0xA5,0xA7,0xA1,0xA3,0xDD,0xDF,0xD9,0xDB,0xD5,0xD7,0xD1,0xD3,0xCD,0xCF,0xC9,0xCB,0xC5,0xC7,0xC1,0xC3,0xFD,0xFF,0xF9,0xFB,0xF5,0xF7,0xF1,0xF3,0xED,0xEF,0xE9,0xEB,0xE5,0xE7,0xE1,0xE3};
t1u const __tS::cECCB[0x100]={
0x00,0xF4,0xF5,0x01,0xF7,0x03,0x02,0xF6,0xF3,0x07,0x06,0xF2,0x04,0xF0,0xF1,0x05,0xFB,0x0F,0x0E,0xFA,0x0C,0xF8,0xF9,0x0D,0x08,0xFC,0xFD,0x09,0xFF,0x0B,0x0A,0xFE,0xEB,0x1F,0x1E,0xEA,0x1C,0xE8,0xE9,0x1D,0x18,0xEC,0xED,0x19,0xEF,0x1B,0x1A,0xEE,0x10,0xE4,0xE5,0x11,0xE7,0x13,0x12,0xE6,0xE3,0x17,0x16,0xE2,0x14,0xE0,0xE1,0x15,0xCB,0x3F,0x3E,0xCA,0x3C,0xC8,0xC9,0x3D,0x38,0xCC,0xCD,0x39,0xCF,0x3B,0x3A,0xCE,0x30,0xC4,0xC5,0x31,0xC7,0x33,0x32,0xC6,0xC3,0x37,0x36,0xC2,0x34,0xC0,0xC1,0x35,0x20,0xD4,0xD5,0x21,0xD7,0x23,0x22,0xD6,0xD3,0x27,0x26,0xD2,0x24,0xD0,0xD1,0x25,0xDB,0x2F,0x2E,0xDA,0x2C,0xD8,0xD9,0x2D,0x28,0xDC,0xDD,0x29,0xDF,0x2B,0x2A,0xDE,
0x8B,0x7F,0x7E,0x8A,0x7C,0x88,0x89,0x7D,0x78,0x8C,0x8D,0x79,0x8F,0x7B,0x7A,0x8E,0x70,0x84,0x85,0x71,0x87,0x73,0x72,0x86,0x83,0x77,0x76,0x82,0x74,0x80,0x81,0x75,0x60,0x94,0x95,0x61,0x97,0x63,0x62,0x96,0x93,0x67,0x66,0x92,0x64,0x90,0x91,0x65,0x9B,0x6F,0x6E,0x9A,0x6C,0x98,0x99,0x6D,0x68,0x9C,0x9D,0x69,0x9F,0x6B,0x6A,0x9E,0x40,0xB4,0xB5,0x41,0xB7,0x43,0x42,0xB6,0xB3,0x47,0x46,0xB2,0x44,0xB0,0xB1,0x45,0xBB,0x4F,0x4E,0xBA,0x4C,0xB8,0xB9,0x4D,0x48,0xBC,0xBD,0x49,0xBF,0x4B,0x4A,0xBE,0xAB,0x5F,0x5E,0xAA,0x5C,0xA8,0xA9,0x5D,0x58,0xAC,0xAD,0x59,0xAF,0x5B,0x5A,0xAE,0x50,0xA4,0xA5,0x51,0xA7,0x53,0x52,0xA6,0xA3,0x57,0x56,0xA2,0x54,0xA0,0xA1,0x55};
t4u const __tS::cEDC[0x100]={
0x00000000,0x90910101,0x91210201,0x01B00300,0x92410401,0x02D00500,0x03600600,0x93F10701,0x94810801,0x04100900,0x05A00A00,0x95310B01,0x06C00C00,0x96510D01,0x97E10E01,0x07700F00,0x99011001,0x09901100,0x08201200,0x98B11301,0x0B401400,0x9BD11501,0x9A611601,0x0AF01700,0x0D801800,0x9D111901,0x9CA11A01,0x0C301B00,0x9FC11C01,0x0F501D00,0x0EE01E00,0x9E711F01,0x82012001,0x12902100,0x13202200,0x83B12301,0x10402400,0x80D12501,0x81612601,0x11F02700,0x16802800,0x86112901,0x87A12A01,0x17302B00,0x84C12C01,0x14502D00,0x15E02E00,0x85712F01,0x1B003000,0x8B913101,0x8A213201,0x1AB03300,0x89413401,0x19D03500,0x18603600,0x88F13701,0x8F813801,0x1F103900,0x1EA03A00,0x8E313B01,0x1DC03C00,0x8D513D01,0x8CE13E01,0x1C703F00,
0xB4014001,0x24904100,0x25204200,0xB5B14301,0x26404400,0xB6D14501,0xB7614601,0x27F04700,0x20804800,0xB0114901,0xB1A14A01,0x21304B00,0xB2C14C01,0x22504D00,0x23E04E00,0xB3714F01,0x2D005000,0xBD915101,0xBC215201,0x2CB05300,0xBF415401,0x2FD05500,0x2E605600,0xBEF15701,0xB9815801,0x29105900,0x28A05A00,0xB8315B01,0x2BC05C00,0xBB515D01,0xBAE15E01,0x2A705F00,0x36006000,0xA6916101,0xA7216201,0x37B06300,0xA4416401,0x34D06500,0x35606600,0xA5F16701,0xA2816801,0x32106900,0x33A06A00,0xA3316B01,0x30C06C00,0xA0516D01,0xA1E16E01,0x31706F00,0xAF017001,0x3F907100,0x3E207200,0xAEB17301,0x3D407400,0xADD17501,0xAC617601,0x3CF07700,0x3B807800,0xAB117901,0xAAA17A01,0x3A307B00,0xA9C17C01,0x39507D00,0x38E07E00,0xA8717F01,
0xD8018001,0x48908100,0x49208200,0xD9B18301,0x4A408400,0xDAD18501,0xDB618601,0x4BF08700,0x4C808800,0xDC118901,0xDDA18A01,0x4D308B00,0xDEC18C01,0x4E508D00,0x4FE08E00,0xDF718F01,0x41009000,0xD1919101,0xD0219201,0x40B09300,0xD3419401,0x43D09500,0x42609600,0xD2F19701,0xD5819801,0x45109900,0x44A09A00,0xD4319B01,0x47C09C00,0xD7519D01,0xD6E19E01,0x46709F00,0x5A00A000,0xCA91A101,0xCB21A201,0x5BB0A300,0xC841A401,0x58D0A500,0x5960A600,0xC9F1A701,0xCE81A801,0x5E10A900,0x5FA0AA00,0xCF31AB01,0x5CC0AC00,0xCC51AD01,0xCDE1AE01,0x5D70AF00,0xC301B001,0x5390B100,0x5220B200,0xC2B1B301,0x5140B400,0xC1D1B501,0xC061B601,0x50F0B700,0x5780B800,0xC711B901,0xC6A1BA01,0x5630BB00,0xC5C1BC01,0x5550BD00,0x54E0BE00,0xC471BF01,
0x6C00C000,0xFC91C101,0xFD21C201,0x6DB0C300,0xFE41C401,0x6ED0C500,0x6F60C600,0xFFF1C701,0xF881C801,0x6810C900,0x69A0CA00,0xF931CB01,0x6AC0CC00,0xFA51CD01,0xFBE1CE01,0x6B70CF00,0xF501D001,0x6590D100,0x6420D200,0xF4B1D301,0x6740D400,0xF7D1D501,0xF661D601,0x66F0D700,0x6180D800,0xF111D901,0xF0A1DA01,0x6030DB00,0xF3C1DC01,0x6350DD00,0x62E0DE00,0xF271DF01,0xEE01E001,0x7E90E100,0x7F20E200,0xEFB1E301,0x7C40E400,0xECD1E501,0xED61E601,0x7DF0E700,0x7A80E800,0xEA11E901,0xEBA1EA01,0x7B30EB00,0xE8C1EC01,0x7850ED00,0x79E0EE00,0xE971EF01,0x7700F000,0xE791F101,0xE621F201,0x76B0F300,0xE541F401,0x75D0F500,0x7460F600,0xE4F1F701,0xE381F801,0x7310F900,0x72A0FA00,0xE231FB01,0x71C0FC00,0xE151FD01,0xE0E1FE01,0x7070FF00};
struct __tX__{tFi::tL mAC,mZZ,mZI;
v f(tFi::tL p)rK{mAC=mZI=(tFi::tL)0;mZZ=p;}
v fAC(tFi::tL p)rK{
if((p>>(t1u)0x14)!=(mAC>>(t1u)0x14)){t8u const E=(p+0x40)>>7;t8u D=(mZZ+0x40)>>7;
if(!D){D=1;}printf("Compressing (%02ld%%)\r",(100*E)/D);}mAC=p;}
v fZI(tFi::tL p)rK{
if((p>>(t1u)0x14)!=(mZI>>(t1u)0x14)){t8u const A=(p+0x40)>>7;t8u D=(mZZ+0x40)>>7;
if(!D){D=1;}printf("Decompressing (%02ld%%)\r",(100*A)/D);}mZI=p;}};
static __tX__ __nX__;
static v fsRi_h(tFi&p,t1u T,t8u N)rL{--N;try{p.uK_h(t1u(((N>=32)<<7)|((N&31)<<2)|T));}catch(tHr){throw;}N>>=5;
while(N){try{p.uK_h(t1u(((N>=128)<<7)|(N&127)));}catch(tHr){throw;}N>>=7;}}
static t4u wsRi_h(t8u N,t4u E,t1u T,tFi const&p,tFi&q)rL{try{fsRi_h(q,T,N);}catch(tHr){throw(tHr)0;}__tS G;tFi::tL Z;
switch(T){
case 0:while(N--){try{p.uRd_h(&G,0x930);}catch(tHr){throw(tHr)0;}E=G.kEDC(E);
try{q.uRi_h(&G(0),0x930),Z=p.kTl_h();}catch(tHr){throw(tHr)0;}__nX__.fAC(Z);}
r__e 1:while(N--){try{p.uRd_h(&G,0x930);}catch(tHr){throw(tHr)0;}E=G.kEDC(E);
try{q.uRi_h(&G(3),0x003),q.uRi_h(&G(4),0x800),Z=p.kTl_h();}catch(tHr){throw(tHr)0;}__nX__.fAC(Z);}
r__e 2:while(N--){try{p.uRd_h(&G,0x930);}catch(tHr){throw(tHr)0;}E=G.kEDC(E);
try{q.uRi_h(&G(3),0x003),q.uRi_h(&G(5),0x804),Z=p.kTl_h();}catch(tHr){throw(tHr)0;}__nX__.fAC(Z);}
r__e 3:while(N--){try{p.uRd_h(&G,0x930);}catch(tHr){throw(tHr)0;}E=G.kEDC(E);
try{q.uRi_h(&G(3),0x003),q.uRi_h(&G(5),0x918),Z=p.kTl_h();}catch(tHr){throw(tHr)0;}__nX__.fAC(Z);}}return E;}
static v A(tFi const&p,tFi&q)rK{tFi::tL lZZ;
try{lZZ=p.kLh_h();}catch(tHr){goto laIO;}__nX__.f(lZZ);t8u l;
if(t8u(lZZ%0x930)){goto laMd;}
l=t8u(lZZ/0x930);
if(!l){goto laTo;}
try{p.uSkSt_h((tFi::tL)0);q.uSkSt_h((tFi::tL)0);
q.uK_h((t1u)'E'),q.uK_h((t1u)'C');q.uK_h((t1u)'M');q.uK_h((t1u)0U);}catch(tHr){goto laIO;}
{__tS lS;t8u lTT[4]={0,0,0,0},lN=0;tFi::tL lsl;t4u lE=0;tFi::tL lZI(0),lZJ(0);t1u lT,lTCr;
try{p.uRd_h(&lS,0x930);}catch(tHr){goto laIO;}lT=lS.kT(),lTCr=lT,--l;goto la;
while(l--){
try{p.uRd_h(&lS,0x930);}catch(tHr){goto laIO;}lT=lS.kT();
la:
if(lT==lTCr){++lN;}
ih{lTT[lTCr]+=lN;
try{p.uSkSt_h(lZJ),lE=wsRi_h(lN,lE,lTCr,p,q);p.uSkCr_h((tFi::tL)0x930);}catch(tHr){goto laIO;}
lZJ=lZI,lTCr=lT,lN=1;}lZI+=0x930;}
lTT[lTCr]+=lN;
try{p.uSkSt_h(lZJ),lE=wsRi_h(lN,lE,lTCr,p,q);p.uSkCr_h((tFi::tL)0x930);fsRi_h(q,0,0);}catch(tHr){goto laIO;}
try{q.uK_h(t1u(lE>>0x00)),q.uK_h(t1u(lE>>0x08)),q.uK_h(t1u(lE>>0x10)),q.uK_h(t1u(lE>>0x18));}catch(tHr){goto laIO;}
printf("Literal bytes...........%ldx ( * 2352 )\n",lTT[0]);
printf("Mode 1 sectors..........%ldx\n",lTT[1]);
printf("Mode 2 form 1 sectors...%ldx\n",lTT[2]);
printf("Mode 2 form 2 sectors...%ldx\n",lTT[3]);try{lsl=q.kTl_h();}catch(tHr){goto laIO;}
printf("Compressed %" oP8 " bytes->%" oP8 " bytes\n",(t8u)lZZ,(t8u)lsl);printf("Done.\n");return;}
laIO:printf("I/O error has occurred! =o You may have to try again.\n"
"Do not disturb disk, or is your disk failing? o.O\n");return;
laMd:printf("File is detected to be not a CD-ROM file.\n"
"Your CD-ROM file must a multiple of 2352 bytes.\n"
"This program cannot handle CD files of non-2352-byte-sized sectors.\n");return;
laTo:printf("Don't troll! -.- This is not a CD-ROM file.\n"
"File size is zero byte!\n");return;}
static v B(tFi const&p,tFi&q)rK{
__tS lS;
tFi::tL lLcL;
tFi::tL lsl;t8u lTT[4];t4u lE;
try{lLcL=p.kLh_h();}catch(tHr){goto laIO;}
if(lLcL<5){goto laTo;}
p.uSkSt_h((tFi::tL)0),q.uSkSt_h((tFi::tL)0);
try{
if(p.kK_h()!='E'||p.kK_h()!='C'||p.kK_h()!='M'||p.kK_h()){goto laHd;}}catch(tHr){goto laIO;}
__nX__.f(lLcL);lTT[0]=lTT[1]=lTT[2]=lTT[3]=0;lE=0;
for(;;){t1u lC;try{lC=p.kK_h();}catch(tHr){goto laIO;}
t1u const T=(t1u)(lC&3);
t4u lBt=5;
t4u N=(lC>>2)&0x1F;
while(lC&0x80){try{lC=p.kK_h();}catch(tHr){goto laIO;}N|=((t4u)(lC&0x7F))<<lBt;lBt+=7;}
if(N==0xFFFFFFFFU){break;}++N;
if(N>=0x80000000U){printf("N>=0x80000000\n");goto laKo;}
lTT[T]+=N;
switch(T){
case 0:
while(N--){lE=lS.kM0_(p,lE),q.uRi_h(&lS,0x0930);try{lsl=p.kTl_h();}catch(tHr){goto laIO;}__nX__.fZI(lsl);}
r__e 1:
while(N--){lE=lS.kM1_(p,lE),q.uRi_h(&lS,0x0930);try{lsl=p.kTl_h();}catch(tHr){goto laIO;}__nX__.fZI(lsl);}
r__e 2:
while(N--){lE=lS.kM21(p,lE),q.uRi_h(&lS,0x0930);try{lsl=p.kTl_h();}catch(tHr){goto laIO;}__nX__.fZI(lsl);}
r__e 3:
while(N--){lE=lS.kM22(p,lE),q.uRi_h(&lS,0x0930);try{lsl=p.kTl_h();}catch(tHr){goto laIO;}__nX__.fZI(lsl);}break;}}
if(!p.kbRd(&lS,4)){goto laIO;}
printf("Literal bytes...........%ldx\n",lTT[0]);
printf("Mode 1 sectors..........%ldx\n",lTT[1]);
printf("Mode 2 form 1 sectors...%ldx\n",lTT[2]);
printf("Mode 2 form 2 sectors...%ldx\n",lTT[3]);try{lsl=q.kTl_h();}catch(tHr){goto laIO;}
printf("Decompressed %ld bytes->%ld bytes\n",(t8u)lLcL,(t8u)lsl);
if(lS(0)!=xWL(lE)){printf("EDC er(%08X,should be %08X)\n",lE,xWL(lS(0)));goto laKo;}
printf("Done.\n");return;
laKo:printf("Corrupt ECM fl!\n");return;
laIO:printf("I/O error!\n");return;
laHd:printf("The header of the file is not found to be an ECM file. -.-\n"
"Have you selected the correct file?\n");return;
laTo:printf("Don't troll! -.- This is not an ECM file.\n");return;}
#include<string.h>
int main(int p,char**q){/*char l[1024];
if(p==2){
t4u L=strlen(q[1]);
if(L<512){memcpy(l,q[1],L); INCOMPLETE
}
}*/
tFi a,b;
try{
a.ARB_h("");
b.AWB_h("");
A(a,b);
B(b,a);
printf("Mission accomplished ...\n");}catch(tHr){printf("Mission over ...\n");}
return 0;}