Skip to content

Commit

Permalink
Add --decompress switch.
Browse files Browse the repository at this point in the history
  • Loading branch information
unknownbrackets committed Oct 11, 2015
1 parent fce16e9 commit 943f300
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
17 changes: 15 additions & 2 deletions cli/cli.cpp
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <string>
#include "../src/compress.h"
Expand All @@ -20,6 +21,7 @@ void show_help(const char *arg0) {
fprintf(stderr, " --quiet Suppress status output\n");
fprintf(stderr, " --crc Log CRC32 checksums, ignore output files and methods\n");
fprintf(stderr, " --fast Use only basic zlib or lz4 for fastest result\n");
fprintf(stderr, " --decompress Write out to raw ISO, decompressing as needed\n");
fprintf(stderr, " --block=N Specify a block size (default is 2048)\n");
fprintf(stderr, " Most readers only support the 2048 size\n");
fprintf(stderr, " --format=VER Specify cso version (options: cso1, cso2, zso)\n");
Expand Down Expand Up @@ -105,6 +107,7 @@ struct Arguments {
bool smallest;
bool quiet;
bool crc;
bool decompress;
};

void default_args(Arguments &args) {
Expand All @@ -124,6 +127,7 @@ void default_args(Arguments &args) {
args.smallest = false;
args.quiet = false;
args.crc = false;
args.decompress = false;
}

int parse_args(Arguments &args, int argc, char *argv[]) {
Expand Down Expand Up @@ -166,6 +170,8 @@ int parse_args(Arguments &args, int argc, char *argv[]) {
args.fast = true;
} else if (has_arg(i, argv, "--smallest")) {
args.smallest = true;
} else if (has_arg(i, argv, "--decompress")) {
args.decompress = true;
} else if (has_arg_method(i, argv, "--use-", method)) {
args.flags_use |= method;
} else if (has_arg_method(i, argv, "--no-", method)) {
Expand Down Expand Up @@ -220,9 +226,13 @@ int validate_args(const char *arg0, Arguments &args) {
continue;
}

const std::string ext = args.inputs[i].substr(args.inputs[i].size() - 4);
if (ext == ".iso" || ext == ".ISO") {
std::string ext = args.inputs[i].substr(args.inputs[i].size() - 4);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

if (!args.decompress && ext == ".iso") {
args.outputs.push_back(args.inputs[i].substr(0, args.inputs[i].size() - 4) + ".cso");
} else if (args.decompress && (ext == ".cso" || ext == ".zso")) {
args.outputs.push_back(args.inputs[i].substr(0, args.inputs[i].size() - 4) + ".iso");
}
}

Expand Down Expand Up @@ -266,6 +276,9 @@ int validate_args(const char *arg0, Arguments &args) {
if (args.smallest) {
args.flags_final |= maxcso::TASKFLAG_FORCE_ALL;
}
if (args.decompress) {
args.flags_final |= maxcso::TASKFLAG_DECOMPRESS;
}
args.flags_final |= args.flags_fmt;

return 0;
Expand Down
1 change: 1 addition & 0 deletions src/compress.cpp
Expand Up @@ -12,6 +12,7 @@ namespace maxcso {
// Anything above this is insane. This value is even insane.
static const uint32_t MAX_BLOCK_SIZE = 0x40000;

// This actually handles decompression too. They're basically the same.
class CompressionTask {
public:
CompressionTask(uv_loop_t *loop, const Task &t)
Expand Down
4 changes: 3 additions & 1 deletion src/compress.h
Expand Up @@ -7,7 +7,7 @@

namespace maxcso {

static const char *VERSION = "1.4.6";
static const char *VERSION = "1.5.0";

struct Task;

Expand Down Expand Up @@ -43,6 +43,8 @@ enum TaskFlags {
TASKFLAG_NO_LZ4_HC_BRUTE = 0x200,

TASKFLAG_NO_ALL = TASKFLAG_NO_ZLIB | TASKFLAG_NO_ZOPFLI | TASKFLAG_NO_7ZIP | TASKFLAG_NO_LZ4,

TASKFLAG_DECOMPRESS = 0x400,
};

typedef std::function<void (const Task *, TaskStatus status, int64_t pos, int64_t total, int64_t written)> ProgressCallback;
Expand Down
20 changes: 18 additions & 2 deletions src/output.cpp
Expand Up @@ -47,8 +47,14 @@ void Output::SetFile(uv_file file, int64_t srcSize, uint32_t blockSize, CSOForma
const uint32_t sectors = static_cast<uint32_t>((srcSize + blockSize_ - 1) >> blockShift_);
// Start after the header and index, which we'll fill in later.
index_ = new uint32_t[sectors + 1];
// Start after the end of the index data and header.
dstPos_ = sizeof(CSOHeader) + (sectors + 1) * sizeof(uint32_t);
if (flags_ & TASKFLAG_DECOMPRESS) {
// Decompressing, so no header.
// We still track the index for code simplicity, but throw it away.
dstPos_ = 0;
} else {
// Start after the end of the index data and header.
dstPos_ = sizeof(CSOHeader) + (sectors + 1) * sizeof(uint32_t);
}

// TODO: We might be able to optimize shift better by running through the data.
// That would require either a second pass or keeping the entire result in RAM.
Expand Down Expand Up @@ -266,6 +272,9 @@ void Output::HandleReadySector(Sector *sector) {
}

bool Output::ShouldCompress(int64_t pos, uint8_t *buffer) {
if (flags_ & TASKFLAG_DECOMPRESS) {
return false;
}
if (flags_ & TASKFLAG_FORCE_ALL) {
return true;
}
Expand Down Expand Up @@ -299,6 +308,13 @@ void Output::Flush() {
return;
}

if (flags_ & TASKFLAG_DECOMPRESS) {
// Okay, we're done. No header or index to write when decompressing.
state_ |= STATE_INDEX_WRITTEN;
CheckFinish();
return;
}

CSOHeader *header = new CSOHeader;
if (fmt_ == CSO_FMT_ZSO) {
memcpy(header->magic, ZSO_MAGIC, sizeof(header->magic));
Expand Down

0 comments on commit 943f300

Please sign in to comment.