[go: up one dir, main page]

File: Decompressor.cpp

package info (click to toggle)
ancient 2.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,168 kB
  • sloc: cpp: 15,188; makefile: 217; sh: 31
file content (116 lines) | stat: -rw-r--r-- 3,529 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* Copyright (C) Teemu Suutari */

#include "Decompressor.hpp"

#include <memory>
#include <vector>

#include "BZIP2Decompressor.hpp"
#include "CompactDecompressor.hpp"
#include "CompressDecompressor.hpp"
#include "CRMDecompressor.hpp"
#include "DEFLATEDecompressor.hpp"
#include "DMSDecompressor.hpp"
#include "FreezeDecompressor.hpp"
#include "IMPDecompressor.hpp"
#include "LOBDecompressor.hpp"
#include "MMCMPDecompressor.hpp"
#include "PackDecompressor.hpp"
#include "PPDecompressor.hpp"
#include "RNCDecompressor.hpp"
#include "SCOCompressDecompressor.hpp"
#include "StoneCrackerDecompressor.hpp"
#include "TPWMDecompressor.hpp"
#include "VicXDecompressor.hpp"
#include "XPKMain.hpp"

namespace ancient::internal
{

// ---

static std::vector<std::pair<bool(*)(uint32_t),std::shared_ptr<Decompressor>(*)(const Buffer&,bool,bool)>> decompressors={
	{BZIP2Decompressor::detectHeader,BZIP2Decompressor::create},
	{CompactDecompressor::detectHeader,CompactDecompressor::create},
	{CompressDecompressor::detectHeader,CompressDecompressor::create},
	{CRMDecompressor::detectHeader,CRMDecompressor::create},
	{DEFLATEDecompressor::detectHeader,DEFLATEDecompressor::create},
	{DMSDecompressor::detectHeader,DMSDecompressor::create},
	{FreezeDecompressor::detectHeader,FreezeDecompressor::create},
	{IMPDecompressor::detectHeader,IMPDecompressor::create},
	{LOBDecompressor::detectHeader,LOBDecompressor::create},
	{MMCMPDecompressor::detectHeader,MMCMPDecompressor::create},
	{PackDecompressor::detectHeader,PackDecompressor::create},
	{PPDecompressor::detectHeader,PPDecompressor::create},
	{RNCDecompressor::detectHeader,RNCDecompressor::create},
	{SCOCompressDecompressor::detectHeader,SCOCompressDecompressor::create},
	{TPWMDecompressor::detectHeader,TPWMDecompressor::create},
	{VicXDecompressor::detectHeader,VicXDecompressor::create},
	{XPKMain::detectHeader,XPKMain::create},
	// Putting StoneCracker last since detection can be accidentally be detected instead of correct format
	{StoneCrackerDecompressor::detectHeader,StoneCrackerDecompressor::create}
	};

std::shared_ptr<Decompressor> Decompressor::create(const Buffer &packedData,bool exactSizeKnown,bool verify)
{
	try
	{
		uint32_t hdr{(packedData.size()>=4)?packedData.readBE32(0):(uint32_t(packedData.readBE16(0))<<16)};
		for (auto &it : decompressors)
		{
			if (it.first(hdr)) return it.second(packedData,exactSizeKnown,verify);
		}
		throw InvalidFormatError();
	} catch (const Buffer::Error&) {
		throw InvalidFormatError();
	}
}

bool Decompressor::detect(const Buffer &packedData) noexcept
{
	if (packedData.size()<2) return false;
	try
	{
		uint32_t hdr{(packedData.size()>=4)?packedData.readBE32(0):(uint32_t(packedData.readBE16(0))<<16)};
		for (auto &it : decompressors)
			if (it.first(hdr)) return true;
		return false;
	} catch (const Buffer::Error&) {
		return false;
	}
}

void Decompressor::decompress(Buffer &rawData,bool verify)
{
	// Simplifying the implementation of sub-decompressors. Just let the buffer-exception pass here,
	// and that will get translated into Decompressor exceptions
	try
	{
		decompressImpl(rawData,verify);
	} catch (const Buffer::Error&) {
		throw DecompressionError();
	}
}

size_t Decompressor::getImageSize() const noexcept
{
	return 0;
}

size_t Decompressor::getImageOffset() const noexcept
{
	return 0;
}

// 1G should be enough for everyone (this is retro!)
size_t Decompressor::getMaxPackedSize() noexcept
{
	return 0x4000'0000U;
}

size_t Decompressor::getMaxRawSize() noexcept
{
	return 0x4000'0000U;
}

}