|
31 | 31 | #include <cstdint> |
32 | 32 | #include <ios> |
33 | 33 | #include <istream> |
34 | | -#include <limits> |
35 | 34 | #include <map> |
36 | 35 | #include <memory> |
37 | 36 | #include <numeric> |
@@ -788,9 +787,9 @@ class nemesis_internal { |
788 | 787 | } |
789 | 788 |
|
790 | 789 | template <typename Compare> |
791 | | - static std::streamoff encode( |
792 | | - std::istream& source, std::ostream& dest, nemesis_mode mode, |
793 | | - std::streamoff const length, Compare&& comp) { |
| 790 | + static std::stringstream encode( |
| 791 | + std::istream& source, nemesis_mode mode, std::streamoff const length, |
| 792 | + Compare&& comp) { |
794 | 793 | auto compare = std::forward<Compare>(comp); |
795 | 794 | // Seek to start and clear all errors. |
796 | 795 | source.clear(); |
@@ -1023,6 +1022,8 @@ class nemesis_internal { |
1023 | 1022 | // This is no longer needed. |
1024 | 1023 | count_map.clear(); |
1025 | 1024 |
|
| 1025 | + // This is what we output. |
| 1026 | + std::stringstream dest; |
1026 | 1027 | // We now have a prefix-free code map associating the RLE-encoded nibble |
1027 | 1028 | // runs with their code. Now we write the file. |
1028 | 1029 | // Write header. |
@@ -1080,7 +1081,7 @@ class nemesis_internal { |
1080 | 1081 | } |
1081 | 1082 | // Fill remainder of last byte with zeroes and write if needed. |
1082 | 1083 | bits.flush(); |
1083 | | - return dest.tellp(); |
| 1084 | + return dest; |
1084 | 1085 | } |
1085 | 1086 | }; |
1086 | 1087 |
|
@@ -1122,33 +1123,23 @@ bool nemesis::encode(std::istream& source, std::ostream& dest) { |
1122 | 1123 | value = new_value; |
1123 | 1124 | } |
1124 | 1125 |
|
1125 | | - std::array<std::stringstream, 4> buffers; |
1126 | 1126 | using nemesis_mode = nemesis_internal::nemesis_mode; |
1127 | 1127 | // Four different attempts to encode, for improved file size. |
1128 | | - std::array sizes{ |
| 1128 | + std::array buffers{ |
1129 | 1129 | nemesis_internal::encode( |
1130 | | - str_source, buffers[0], nemesis_mode::normal, size, compare_node{}), |
| 1130 | + str_source, nemesis_mode::normal, size, compare_node{}), |
1131 | 1131 | nemesis_internal::encode( |
1132 | | - str_source, buffers[1], nemesis_mode::normal, size, compare_node2{}), |
| 1132 | + str_source, nemesis_mode::normal, size, compare_node2{}), |
1133 | 1133 | nemesis_internal::encode( |
1134 | | - source_xor, buffers[2], nemesis_mode::progressive_xor, size, |
1135 | | - compare_node{}), |
| 1134 | + source_xor, nemesis_mode::progressive_xor, size, compare_node{}), |
1136 | 1135 | nemesis_internal::encode( |
1137 | | - source_xor, buffers[3], nemesis_mode::progressive_xor, size, |
1138 | | - compare_node2{})}; |
| 1136 | + source_xor, nemesis_mode::progressive_xor, size, compare_node2{})}; |
1139 | 1137 |
|
1140 | 1138 | // Figure out what was the best encoding. |
1141 | | - std::streamoff best_size = std::numeric_limits<std::streamoff>::max(); |
1142 | | - size_t best_stream = 0; |
1143 | | - for (size_t ii = 0; ii < sizes.size(); ii++) { |
1144 | | - if (sizes[ii] < best_size) { |
1145 | | - best_size = sizes[ii]; |
1146 | | - best_stream = ii; |
1147 | | - } |
1148 | | - } |
| 1139 | + auto& best_iter = *std::ranges::min_element(buffers, {}, &std::stringstream::tellp); |
1149 | 1140 |
|
1150 | | - buffers[best_stream].seekg(0); |
1151 | | - dest << buffers[best_stream].rdbuf(); |
| 1141 | + best_iter.seekg(0); |
| 1142 | + dest << best_iter.rdbuf(); |
1152 | 1143 | return true; |
1153 | 1144 | } |
1154 | 1145 |
|
|
0 commit comments