Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <iostream>
- #include <string>
- #include <iterator>
- #include <fstream>
- #include <stdlib.h>
- #include <stdio.h>
- #include <memory.h>
- #include <vector>
- #pragma warning(disable:4996)
- #define __attribute__(A)
- #if _WIN32
- unsigned int s32(unsigned int i)
- {
- return ((i >> 24) | (i << 24) | ((i & 0x00FF0000) >> 8) | ((i & 0x0000FF00) << 8));
- }
- unsigned short s16(unsigned short s)
- {
- return (s >> 8) | (s << 8);
- }
- #else
- #include <arpa/inet.h>
- unsigned int s32(unsigned int i) { return ntohl(i); }
- unsigned int s16(unsigned short s) { return ntohs(s); }
- #endif
- #ifndef ATTRIBUTE_ALIGN
- # define ATTRIBUTE_ALIGN(v) __attribute__((aligned(v)))
- #endif
- #define CHARBITS12 11
- #define CHARBITS9 9
- #define CODESIZE12 (1<<CHARBITS12)
- #define CODESIZE9 (1<<CHARBITS9)
- #define ASRSIZE12 4096
- #define ASRSIZE9 512
- #define TREESTACKSIZE 256
- static int getbitsc(unsigned char *, int, int);
- static int getbit1c(unsigned char *, int);
- static int readtree9(unsigned char *, unsigned short *, unsigned short *, unsigned short *);
- static int readtree12(unsigned char *, unsigned short *, unsigned short *, unsigned short *);
- static int Rvl_decode_ash_size(const unsigned char* s);
- int Rvl_decode_ash(unsigned char *d, unsigned char *s);
- extern void* DecompAsh(const void* src);
- static int bitlen[2], ccnt[2], wptr[2];
- static unsigned bitcode[2];
- static unsigned char work[(ASRSIZE9 + ASRSIZE9 + 1 + ASRSIZE12 + ASRSIZE12 + 1) * 4] ATTRIBUTE_ALIGN(32);
- /*---------------------------------------------------------------------------*
- Name: DecmoAsh
- Description: Expands an ASH-compressed file
- Arguments: src
- memHandle
- Returns: None.
- *---------------------------------------------------------------------------*/
- void*
- DecompAsh(void* src)
- {
- int dstSize = Rvl_decode_ash_size(static_cast<const unsigned char*>(src));
- printf("dstSize: %i\n", dstSize);
- void* dstBuf = malloc(dstSize);
- Rvl_decode_ash(static_cast<unsigned char*>(dstBuf), static_cast<unsigned char*>(src));
- return dstBuf;
- }
- static int Rvl_decode_ash_size(const unsigned char* s)
- {
- return (s[5] << 16) | (s[6] << 8) | s[7];
- }
- /* Main ASH expansion*/
- int Rvl_decode_ash(unsigned char *d, unsigned char *s)
- {
- int i, j, k, q, t, root9, root12;
- unsigned short *left9, *right9, *left12, *right12, *stack;
- t = (s[5] << 16) | (s[6] << 8) | s[7]; /* Expanded size */
- k = (s[8] << 24) | (s[9] << 16) | (s[10] << 8) | s[11]; /* Flag information offset*/
- /* Initialization */
- wptr[0] = 12; wptr[1] = k;
- bitlen[0] = bitlen[1] = 0;
- ccnt[0] = CODESIZE9; ccnt[1] = CODESIZE12;
- left9 = (unsigned short *)work;
- right9 = left9 + (2 * CODESIZE9 - 1) * sizeof(short);
- left12 = right9 + (2 * CODESIZE9 - 1) * sizeof(short);
- right12 = left12 + (2 * CODESIZE12 - 1) * sizeof(short);
- stack = right12 + (2 * CODESIZE12 - 1) * sizeof(short);
- (void)getbitsc(s, 32, 0); (void)getbitsc(s, 32, 1);
- root9 = readtree9(s, left9, right9, stack);
- printf("root9: %i\n", root9);
- root12 = readtree12(s, left12, right12, stack);
- printf("root12: %i\n", root12);
- /* Expansion*/
- for (q = 0; q < t;) {
- j = root9;
- while (j >= CODESIZE9) {
- j = (getbit1c(s, 0)) ? right9[j] : left9[j];
- }
- if (j < 256) {
- d[q++] = (unsigned char)j;
- }
- else {
- i = root12;
- while (i >= CODESIZE12) {
- i = (getbit1c(s, 1)) ? right12[i] : left12[i];
- }
- i = q - i - 1; /* Distance */
- j -= 253;
- for (; j > 0; j--, q++, i++)d[q] = d[i];
- }
- }
- return(q);
- }
- int getbitsc(unsigned char *s, int size, int f)
- {
- int k, m;
- unsigned i, j, g;
- k = wptr[f]; m = bitlen[f]; g = bitcode[f];
- if (m + size > 32) {
- j = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]);
- i = (g >> (32 - size)) | (j >> (64 - size - m));
- m += size - 32; bitcode[f] = j << m; bitlen[f] = m;
- wptr[f] = k + 4;
- }
- else if (m + size == 32) {
- i = g >> (32 - size);
- bitcode[f] = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]);
- wptr[f] = k + 4; bitlen[f] = 0;
- }
- else {
- i = g >> (32 - size); bitcode[f] = g << size; bitlen[f] = m + size;
- }
- return((int)i);
- }
- int getbit1c(unsigned char *s, int f)
- {
- int k, m;
- unsigned i, g;
- k = wptr[f]; m = bitlen[f]; g = bitcode[f];
- i = g >> 31;
- if (m == 31) {
- bitcode[f] = (unsigned)((s[k] << 24) | (s[k + 1] << 16) | (s[k + 2] << 8) | s[k + 3]);
- wptr[f] = k + 4; bitlen[f] = 0;
- }
- else {
- bitcode[f] = g << 1; bitlen[f] = m + 1;
- }
- return((int)i);
- }
- int readtree9(unsigned char *s, unsigned short *left9, unsigned short *right9, unsigned short *stack)
- {
- int f, j, m, z, sp;
- for (j = m = ccnt[0], sp = 0;;) {
- if (getbit1c(s, 0)) {
- stack[sp] = (unsigned short)(0x8000 | j);
- stack[sp + 1] = (unsigned short)(0x4000 | j);
- j++; m++; sp += 2;
- if (sp >= TREESTACKSIZE) {
- // OS_Printf("stack over flow\n");
- }
- }
- else {
- z = getbitsc(s, CHARBITS9, 0);
- while (1) {
- f = (int)stack[--sp];
- if (f & 0x8000) {
- right9[f & 0x3FFF] = (unsigned short)z;
- z = f & 0x3FFF;
- if (sp == 0)return(z);
- }
- else {
- left9[f & 0x3FFF] = (unsigned short)z;
- j = m;
- break;
- }
- }
- }
- }
- }
- int readtree12(unsigned char *s, unsigned short *left12, unsigned short *right12, unsigned short *stack)
- {
- int f, j, m, z, sp;
- for (j = m = ccnt[1], sp = 0;;) {
- if (getbit1c(s, 1)) {
- //if (sp < 100) printf("sp: %i, j: %i\n", sp, 0x8000 | j);
- stack[sp] = (unsigned short)(0x8000 | j);
- stack[sp + 1] = (unsigned short)(0x4000 | j);
- j++; m++; sp += 2;
- if (sp >= TREESTACKSIZE) {
- //printf("stack over flow\n");
- }
- }
- else {
- z = getbitsc(s, CHARBITS12, 1);
- while (1) {
- f = (int)stack[--sp];
- if (f & 0x8000) {
- right12[f & 0x3FFF] = (unsigned short)z;
- z = f & 0x3FFF;
- if (sp == 0)return(z);
- }
- else {
- left12[f & 0x3FFF] = (unsigned short)z;
- j = m;
- break;
- }
- }
- }
- }
- }
- std::vector<uint8_t> readFile(std::string filename) {
- std::ifstream file(filename, std::ios::binary);
- file.unsetf(std::ios::skipws);
- std::streampos fileSize;
- file.seekg(0, std::ios::end);
- fileSize = file.tellg();
- file.seekg(0, std::ios::beg);
- std::vector<uint8_t> vec;
- vec.reserve(fileSize);
- vec.insert(vec.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());
- return vec;
- }
- int main() {
- std::cout << "Hello World!\n";
- std::string filePath = "C:/Users/User/source/repos/ConsoleApplication7/Debug/mii.ash";
- std::vector<uint8_t> buffer = readFile(filePath);
- void* out = DecompAsh(buffer.data());
- int size = Rvl_decode_ash_size(static_cast<const unsigned char*>(buffer.data()));
- std::FILE* file = std::fopen("C:/Users/User/source/repos/ConsoleApplication7/Debug/course.arc", "wb");
- size_t numWritten = std::fwrite(out, 1, size * sizeof(uint8_t), file);
- std::fclose(file);
- std::cout << "Success!" << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement