Skip to content

Commit 5eb7413

Browse files
author
Nicolás Comerci
committed
Initial changes for stdin/stdout support
1 parent b8fca25 commit 5eb7413

File tree

1 file changed

+75
-33
lines changed

1 file changed

+75
-33
lines changed

precomp.cpp

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,18 @@
9292

9393
using namespace std;
9494

95+
// This I shamelessly lifted from https://web.archive.org/web/20090907131154/http://www.cs.toronto.edu:80/~ramona/cosmin/TA/prog/sysconf/
96+
// (credit to this StackOverflow answer for pointing me to it https://stackoverflow.com/a/1613677)
97+
// It allows us to portably (at least for Windows/Linux/Mac) set a std stream as binary
98+
#define STDIN 0
99+
#define STDOUT 1
100+
#define STDERR 2
101+
#ifndef __unix
102+
# define SET_BINARY_MODE(handle) setmode(handle, O_BINARY)
103+
#else
104+
# define SET_BINARY_MODE(handle) ((void)0)
105+
#endif
106+
95107
#include "contrib/bzip2/bzlib.h"
96108
#include "contrib/giflib/precomp_gif.h"
97109
#include "contrib/packjpg/precomp_jpg.h"
@@ -125,6 +137,8 @@ int cb; // "checkbuf"
125137
unsigned char in[CHUNK];
126138
unsigned char out[CHUNK];
127139

140+
bool header_already_read = false;
141+
128142
// name of temporary files
129143
char metatempfile[18] = "~temp00000000.dat";
130144
char tempfile0[19] = "~temp000000000.dat";
@@ -1090,7 +1104,7 @@ int init(int argc, char* argv[]) {
10901104

10911105
// dot in output file name? If not, use .pcf extension
10921106
char* dot_at_pos = strrchr(output_file_name, '.');
1093-
if ((dot_at_pos == NULL) || ((backslash_at_pos != NULL) && (backslash_at_pos > dot_at_pos))) {
1107+
if (strcmp(output_file_name, "stdout") != 0 && ((dot_at_pos == NULL) || ((backslash_at_pos != NULL) && (backslash_at_pos > dot_at_pos)))) {
10941108
strcpy(output_file_name + strlen(argv[i]) - 2, ".pcf");
10951109
appended_pcf = true;
10961110
}
@@ -1139,13 +1153,24 @@ int init(int argc, char* argv[]) {
11391153
input_file_given = true;
11401154
input_file_name = argv[i];
11411155

1142-
fin_length = fileSize64(argv[i]);
1156+
if (strcmp(input_file_name, "stdin") == 0) {
1157+
if (operation != P_DECOMPRESS) {
1158+
print_to_console("ERROR: Reading from stdin only supported for recompressing.\n");
1159+
exit(1);
1160+
}
1161+
// Read binary from stdin
1162+
SET_BINARY_MODE(STDIN);
1163+
fin = stdin;
1164+
}
1165+
else {
1166+
fin_length = fileSize64(argv[i]);
11431167

1144-
fin = fopen(argv[i],"rb");
1145-
if (fin == NULL) {
1146-
printf("ERROR: Input file \"%s\" doesn't exist\n", input_file_name);
1168+
fin = fopen(argv[i], "rb");
1169+
if (fin == NULL) {
1170+
printf("ERROR: Input file \"%s\" doesn't exist\n", input_file_name);
11471171

1148-
exit(1);
1172+
exit(1);
1173+
}
11491174
}
11501175

11511176
// output file given? If not, use input filename with .pcf extension
@@ -1255,24 +1280,31 @@ int init(int argc, char* argv[]) {
12551280
read_header();
12561281
}
12571282

1258-
if (file_exists(output_file_name)) {
1259-
printf("Output file \"%s\" exists. Overwrite (y/n)? ", output_file_name);
1260-
char ch = get_char_with_echo();
1261-
if ((ch != 'Y') && (ch != 'y')) {
1262-
printf("\n");
1263-
exit(0);
1264-
} else {
1265-
#ifndef __unix
1266-
printf("\n\n");
1267-
#else
1268-
printf("\n");
1269-
#endif
1270-
}
1283+
if (output_file_given && strcmp(output_file_name, "stdout") == 0) {
1284+
// Write binary to stdout
1285+
SET_BINARY_MODE(STDOUT);
1286+
fout = stdout;
12711287
}
1272-
fout = fopen(output_file_name,"wb");
1273-
if (fout == NULL) {
1274-
printf("ERROR: Can't create output file \"%s\"\n", output_file_name);
1275-
exit(1);
1288+
else {
1289+
if (file_exists(output_file_name)) {
1290+
printf("Output file \"%s\" exists. Overwrite (y/n)? ", output_file_name);
1291+
char ch = get_char_with_echo();
1292+
if ((ch != 'Y') && (ch != 'y')) {
1293+
printf("\n");
1294+
exit(0);
1295+
} else {
1296+
#ifndef __unix
1297+
printf("\n\n");
1298+
#else
1299+
printf("\n");
1300+
#endif
1301+
}
1302+
}
1303+
fout = fopen(output_file_name,"wb");
1304+
if (fout == NULL) {
1305+
printf("ERROR: Can't create output file \"%s\"\n", output_file_name);
1306+
exit(1);
1307+
}
12761308
}
12771309

12781310
printf("Input file: %s\n",input_file_name);
@@ -2374,14 +2406,17 @@ void denit_compress() {
23742406
}
23752407

23762408
#ifndef PRECOMPDLL
2377-
long long fout_length = fileSize64(output_file_name);
2378-
if (recursion_depth == 0) {
2379-
if (!DEBUG_MODE) {
2380-
printf("%s", string(14,'\b').c_str());
2381-
cout << "100.00% - New size: " << fout_length << " instead of " << fin_length << " " << endl;
2382-
} else {
2383-
cout << "New size: " << fout_length << " instead of " << fin_length << " " << endl;
2384-
}
2409+
if (strcmp(output_file_name, "stdout") != 0) {
2410+
long long fout_length = fileSize64(output_file_name);
2411+
if (recursion_depth == 0) {
2412+
if (!DEBUG_MODE) {
2413+
printf("%s", string(14, '\b').c_str());
2414+
cout << "100.00% - New size: " << fout_length << " instead of " << fin_length << " " << endl;
2415+
}
2416+
else {
2417+
cout << "New size: " << fout_length << " instead of " << fin_length << " " << endl;
2418+
}
2419+
}
23852420
}
23862421
#else
23872422
if (recursion_depth == 0) {
@@ -4571,14 +4606,17 @@ void decompress_file() {
45714606

45724607
fin_pos = tell_64(fin);
45734608

4574-
while (fin_pos < fin_length) {
4609+
auto otf_none_end_check = [](){ return compression_otf_method == OTF_NONE && (feof(fin) || ferror(fin)); };
4610+
4611+
while (!otf_none_end_check() || compression_otf_method != OTF_NONE && decompress_otf_end) {
45754612

45764613
if ((recursion_depth == 0) && (!DEBUG_MODE)) {
45774614
float percent = (fin_pos / (float)fin_length) * 100;
45784615
show_progress(percent, true, true);
45794616
}
45804617

45814618
unsigned char header1 = fin_fgetc();
4619+
if (otf_none_end_check()) break;
45824620
if (header1 == 0) { // uncompressed data
45834621
long long uncompressed_data_length;
45844622
uncompressed_data_length = fin_fget_vlint();
@@ -5390,6 +5428,7 @@ void write_header() {
53905428

53915429
#ifdef COMFORT
53925430
bool check_for_pcf_file() {
5431+
if (header_already_read) return true;
53935432
seek_64(fin, 0);
53945433

53955434
fread(in, 1, 3, fin);
@@ -5429,12 +5468,13 @@ bool check_for_pcf_file() {
54295468
strcpy(output_file_name, header_filename.c_str());
54305469
}
54315470

5471+
header_already_read = true;
54325472
return true;
54335473
}
54345474
#endif
54355475

54365476
void read_header() {
5437-
seek_64(fin, 0);
5477+
if (header_already_read) return;
54385478

54395479
fread(in, 1, 3, fin);
54405480
if ((in[0] == 'P') && (in[1] == 'C') && (in[2] == 'F')) {
@@ -5465,6 +5505,8 @@ void read_header() {
54655505
output_file_name = new char[strlen(header_filename.c_str()) + 1];
54665506
strcpy(output_file_name, header_filename.c_str());
54675507
}
5508+
5509+
header_already_read = true;
54685510
}
54695511

54705512
void convert_header() {

0 commit comments

Comments
 (0)