Skip to content

Commit d27bab2

Browse files
author
Argent77
committed
Merge with devel branch
1 parent 0a44c63 commit d27bab2

15 files changed

+478
-209
lines changed

tileconv/README

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
TILECONV
22
~~~~~~~~
33

4-
Version: 0.3
4+
Version: 0.4
55
Author: Argent77
66

77
This tool allows you to compress or decompress TIS and MOS files provided by
@@ -34,18 +34,30 @@ Options:
3434
2: BC2/DXT3
3535
3: BC3/DXT5
3636
-u Do not apply tile compression.
37-
-o outfile Select output file. (Works with single input file only!)
37+
-o output Select output file or folder.
38+
(Note: Output file works only with single input file!)
3839
-z MOS only: Decompress MBC into compressed MOS (MOSC).
39-
-d Enable color dithering. (deprecated, use -q instead!)
40-
-q level Specify quality vs. speed ratio when converting MBC->MOS
41-
or TBC->TIS. Supported levels: 0..9 (Default: 4)
40+
-q Dec[Enc] Set quality levels for decoding and, optionally, encoding.
41+
Supported levels: 0..9 (Defaults: 4 for decoding, 9 for encoding)
4242
(0=fast and lower quality, 9=slow and higher quality)
43-
Applied level-dependent features:
44-
Dithering: levels 5 to 9
45-
Posterization: levels 0 to 2
46-
Additional techniques: levels 4 to 9
43+
Specify both levels as a single argument. First digit indicates
44+
decoding quality and second digit indicates encoding quality.
45+
Specify '-' as placeholder for default levels.
46+
Example 1: -q 27 (decoding level: 2, encoding level: 7)
47+
Example 2: -q -7 (default decoding level, encoding level: 7)
48+
Example 3: -q 2 (decoding level: 2, default encoding level)
49+
Applied level-dependent features for encoding (DXTn only):
50+
Iterative cluster fit: levels 7 to 9
51+
Single cluster fit: levels 3 to 6
52+
Range fit: levels 0 to 2
53+
Weight color by alpha: levels 5 to 9
54+
Applied level-dependent features for decoding:
55+
Dithering: levels 5 to 9
56+
Posterization: levels 0 to 2
57+
Additional techniques: levels 4 to 9
4758
-j num Number of parallel jobs to speed up the conversion process.
4859
Valid numbers: 0 (autodetect), 1..256 (Default: 0)
60+
-T Treat unrecognized input files as headerless TIS.
4961
-I Show file information and exit.
5062
-V Print version number and exit.
5163

@@ -101,3 +113,9 @@ v0.3 (2014-09-06)
101113
* Better parameter handling
102114
* Added option -I for displaying file stats
103115
* Many fixes and improvements under the hood
116+
117+
v0.4 (2014-09-09)
118+
* Improved visual feedback
119+
* Added output folder support
120+
* Added option "-T" to treat unrecognized files as headerless TIS
121+
* Added quality levels for encoding process

tileconv/colors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ uint32_t Colors::ARGBToPal(uint8_t *src, uint8_t *dst, uint8_t *palette,
6969
if (!quant.setTarget(dst, size)) return 0;
7070
std::memset(palette, 0, 1024);
7171
if (!quant.setPalette(palette, 1024)) return 0;
72-
quant.setSpeed(10 - getOptions().getQuality()); // speed is defined as "10 - quality"
72+
quant.setSpeed(10 - getOptions().getDecodingQuality()); // speed is defined as "10 - quality"
7373

7474
if (!quant.quantize()) return 0;
7575
if (getOptions().isVerbose()) {

tileconv/convert.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ THE SOFTWARE.
3131

3232
Convert::Convert() noexcept
3333
: m_options()
34+
, m_initialized(true)
3435
{
3536
}
3637

@@ -48,13 +49,14 @@ Convert::~Convert() noexcept
4849

4950
bool Convert::init(int argc, char *argv[]) noexcept
5051
{
51-
return m_options.init(argc, argv);
52+
return (m_initialized = m_options.init(argc, argv));
5253
}
5354

5455

5556
bool Convert::execute() noexcept
5657
{
5758
// checking state
59+
if (!isInitialized()) return false;
5860
if (getOptions().getInputCount() == 0) return false;
5961

6062
// Special case: show information of input files only
@@ -75,18 +77,18 @@ bool Convert::execute() noexcept
7577
bool retVal = true;
7678
for (int i = 0; i < getOptions().getInputCount(); i++) {
7779
if (!getOptions().isSilent() && getOptions().getInputCount() > 1) {
78-
std::printf("Processing file %d of %d\n", i+1, getOptions().getInputCount());
80+
std::printf("\nProcessing file %d of %d\n", i+1, getOptions().getInputCount());
7981
}
8082
const std::string &inputFile = getOptions().getInput(i);
8183
std::string outputFile;
8284
if (!inputFile.empty()) {
83-
switch (Options::GetFileType(inputFile)) {
85+
switch (Options::GetFileType(inputFile, getOptions().assumeTis())) {
8486
case FileType::TIS:
8587
// generating output filename
86-
if (!getOptions().isOutput()) {
87-
outputFile = Options::SetFileExt(inputFile, FileType::TBC);
88+
if (getOptions().isOutFile()) {
89+
outputFile = getOptions().getOutPath() + getOptions().getOutFile();
8890
} else {
89-
outputFile = getOptions().getOutput();
91+
outputFile = getOptions().getOutPath() + Options::SetFileExt(inputFile, FileType::TBC);
9092
}
9193
if (outputFile.empty()) {
9294
retVal = false;
@@ -101,7 +103,6 @@ bool Convert::execute() noexcept
101103
if (!getOptions().isSilent()) {
102104
std::printf("Converting TIS -> TBC\n");
103105
std::printf("Input: \"%s\", output: \"%s\"\n", inputFile.c_str(), outputFile.c_str());
104-
std::printf("Converting...\n");
105106
}
106107
if (!gfx.tisToTBC(inputFile, outputFile)) {
107108
retVal = false;
@@ -113,10 +114,10 @@ bool Convert::execute() noexcept
113114
break;
114115
case FileType::MOS:
115116
// generating output filename
116-
if (!getOptions().isOutput()) {
117-
outputFile = Options::SetFileExt(inputFile, FileType::MBC);
117+
if (getOptions().isOutFile()) {
118+
outputFile = getOptions().getOutPath() + getOptions().getOutFile();
118119
} else {
119-
outputFile = getOptions().getOutput();
120+
outputFile = getOptions().getOutPath() + Options::SetFileExt(inputFile, FileType::MBC);
120121
}
121122
if (outputFile.empty()) {
122123
retVal = false;
@@ -131,7 +132,6 @@ bool Convert::execute() noexcept
131132
if (!getOptions().isSilent()) {
132133
std::printf("Converting MOS -> MBC\n");
133134
std::printf("Input: \"%s\", output: \"%s\"\n", inputFile.c_str(), outputFile.c_str());
134-
std::printf("Converting...\n");
135135
}
136136
if (!gfx.mosToMBC(inputFile, outputFile)) {
137137
retVal = false;
@@ -143,10 +143,10 @@ bool Convert::execute() noexcept
143143
break;
144144
case FileType::TBC:
145145
// generating output filename
146-
if (!getOptions().isOutput()) {
147-
outputFile = Options::SetFileExt(inputFile, FileType::TIS);
146+
if (getOptions().isOutFile()) {
147+
outputFile = getOptions().getOutPath() + getOptions().getOutFile();
148148
} else {
149-
outputFile = getOptions().getOutput();
149+
outputFile = getOptions().getOutPath() + Options::SetFileExt(inputFile, FileType::TIS);
150150
}
151151
if (outputFile.empty()) {
152152
retVal = false;
@@ -161,7 +161,6 @@ bool Convert::execute() noexcept
161161
if (!getOptions().isSilent()) {
162162
std::printf("Converting TBC -> TIS\n");
163163
std::printf("Input: \"%s\", output: \"%s\"\n", inputFile.c_str(), outputFile.c_str());
164-
std::printf("Converting...\n");
165164
}
166165
if (!gfx.tbcToTIS(inputFile, outputFile)) {
167166
retVal = false;
@@ -173,10 +172,10 @@ bool Convert::execute() noexcept
173172
break;
174173
case FileType::MBC:
175174
// generating output filename
176-
if (!getOptions().isOutput()) {
177-
outputFile = Options::SetFileExt(inputFile, FileType::MOS);
175+
if (getOptions().isOutFile()) {
176+
outputFile = getOptions().getOutPath() + getOptions().getOutFile();
178177
} else {
179-
outputFile = getOptions().getOutput();
178+
outputFile = getOptions().getOutPath() + Options::SetFileExt(inputFile, FileType::MOS);
180179
}
181180
if (outputFile.empty()) {
182181
retVal = false;
@@ -191,7 +190,6 @@ bool Convert::execute() noexcept
191190
if (!getOptions().isSilent()) {
192191
std::printf("Converting MBC -> MOS\n");
193192
std::printf("Input: \"%s\", output: \"%s\"\n", inputFile.c_str(), outputFile.c_str());
194-
std::printf("Converting...\n");
195193
}
196194
if (!gfx.mbcToMOS(inputFile, outputFile)) {
197195
retVal = false;
@@ -261,8 +259,7 @@ bool Convert::showInfo(const std::string &fileName) noexcept
261259
isMosc = true;
262260

263261
// getting MOSC file size
264-
f.seek(0, SEEK_END);
265-
moscSize = f.tell();
262+
moscSize = f.getsize();
266263
if (moscSize <= 12) {
267264
std::printf("Invalid MOSC size\n");
268265
return false;
@@ -294,8 +291,7 @@ bool Convert::showInfo(const std::string &fileName) noexcept
294291
}
295292
} else {
296293
// reading MOS header into memory
297-
f.seek(0, SEEK_END);
298-
mosSize = f.tell();
294+
mosSize = f.getsize();
299295
if (mosSize < 24) {
300296
std::printf("MOS size too small\n");
301297
return false;

tileconv/convert.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ class Convert
5050
// Display information about the specified filename
5151
bool showInfo(const std::string &fileName) noexcept;
5252

53+
// Returns whether arguments have been initialized successfully.
54+
bool isInitialized() const noexcept { return m_initialized; }
55+
5356
private:
5457
Options m_options;
58+
bool m_initialized;
5559
};
5660

5761
#endif

tileconv/fileio.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,34 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2020
THE SOFTWARE.
2121
*/
2222
#include "fileio.h"
23+
#include <sys/types.h>
24+
#include <sys/stat.h>
25+
#include <unistd.h>
26+
27+
28+
bool File::IsDirectory(const char *fileName) noexcept
29+
{
30+
if (fileName != nullptr) {
31+
struct stat s;
32+
if (stat(fileName, &s) != -1) {
33+
return S_ISDIR(s.st_mode);
34+
}
35+
}
36+
return false;
37+
}
38+
39+
40+
long File::GetFileSize(const char *fileName) noexcept
41+
{
42+
if (fileName != nullptr) {
43+
struct stat s;
44+
if (stat(fileName, &s) != -1) {
45+
return s.st_size;
46+
}
47+
}
48+
return -1L;
49+
}
50+
2351

2452
File::File(const char *fileName, const char *mode) noexcept
2553
: m_file(0)
@@ -204,3 +232,17 @@ void File::perror(const char *s) noexcept
204232
std::perror(s);
205233
}
206234

235+
236+
long File::getsize() noexcept
237+
{
238+
if (m_file) {
239+
long curPos = tell();
240+
if (curPos >= 0 && seek(0, SEEK_END)) {
241+
long size = tell();
242+
seek(curPos, SEEK_SET);
243+
return size;
244+
}
245+
}
246+
return -1L;
247+
}
248+

tileconv/fileio.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ THE SOFTWARE.
3131
*/
3232
class File
3333
{
34+
public:
35+
/** Returns true only if the given path is a directory. */
36+
static bool IsDirectory(const char *fileName) noexcept;
37+
38+
/** Returns size of the given file in bytes. Returns -1 on error. */
39+
static long GetFileSize(const char *fileName) noexcept;
40+
3441
public:
3542
/** Opens a file in the specified mode. */
3643
File(const char *fileName, const char *mode) noexcept;
@@ -105,6 +112,9 @@ class File
105112
/** Prints s and a textual description of the error code stored in the system variable errno to stderr. */
106113
void perror(const char *s) noexcept;
107114

115+
/** Returns the size of the currently open file. Returns -1 on error. */
116+
long getsize() noexcept;
117+
108118
private:
109119
std::FILE *m_file; // current file handle
110120
std::string m_mode; // current file mode

0 commit comments

Comments
 (0)