Skip to content

Commit f470598

Browse files
committedJun 2, 2017
Reduce memory usage of guetzli by about 16 bytes/pixel.
Peak memory usage of the ~1MP station.png file from the test corpus went from 111 MiB to 94 MiB. The memory reduction is achieved by: (1) not storing the opsin dynamic image of the original, since it turns out that recomputing it is not significant, compared to other operations in butteraugli, (2) removing the distance map from GuetzliOutput, since it is not used afterwards, and (3) clearing the previous values from distance map before starting butteraugli calculations. I checked that the golden test passes.
1 parent e2748c8 commit f470598

File tree

7 files changed

+31
-29
lines changed

7 files changed

+31
-29
lines changed
 

‎guetzli/butteraugli_comparator.cc

+25-15
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@
2424

2525
namespace guetzli {
2626

27+
std::vector<std::vector<float> > ComputeOpsinDynamicsImage(
28+
const int width, const int height,
29+
const std::vector<uint8_t>& rgb) {
30+
std::vector<std::vector<float> > out(3);
31+
const double* lut = Srgb8ToLinearTable();
32+
for (int c = 0; c < 3; ++c) {
33+
out[c].resize(width * height);
34+
for (int y = 0, ix = 0; y < height; ++y) {
35+
for (int x = 0; x < width; ++x, ++ix) {
36+
out[c][ix] = lut[rgb[3 * ix + c]];
37+
}
38+
}
39+
}
40+
::butteraugli::OpsinDynamicsImage(width, height, out);
41+
return out;
42+
}
43+
2744
ButteraugliComparator::ButteraugliComparator(const int width, const int height,
2845
const std::vector<uint8_t>* rgb,
2946
const float target_distance,
@@ -32,34 +49,27 @@ ButteraugliComparator::ButteraugliComparator(const int width, const int height,
3249
height_(height),
3350
target_distance_(target_distance),
3451
rgb_orig_(*rgb),
35-
rgb_linear_pregamma_(3, std::vector<float>(width_ * height_)),
3652
comparator_(width_, height_, kButteraugliStep),
3753
distance_(0.0),
38-
distmap_(width_, static_cast<float>(height_)),
39-
stats_(stats) {
40-
const double* lut = Srgb8ToLinearTable();
41-
for (int c = 0; c < 3; ++c) {
42-
for (int y = 0, ix = 0; y < height_; ++y) {
43-
for (int x = 0; x < width_; ++x, ++ix) {
44-
rgb_linear_pregamma_[c][ix] = lut[rgb_orig_[3 * ix + c]];
45-
}
46-
}
47-
}
48-
::butteraugli::OpsinDynamicsImage(width_, height_, rgb_linear_pregamma_);
49-
}
54+
stats_(stats) {}
5055

5156
void ButteraugliComparator::Compare(const OutputImage& img) {
57+
std::vector<std::vector<float> > rgb0 =
58+
ComputeOpsinDynamicsImage(width_, height_, rgb_orig_);
5259
std::vector<std::vector<float> > rgb(3, std::vector<float>(width_ * height_));
5360
img.ToLinearRGB(&rgb);
5461
::butteraugli::OpsinDynamicsImage(width_, height_, rgb);
55-
comparator_.DiffmapOpsinDynamicsImage(rgb_linear_pregamma_, rgb, distmap_);
62+
std::vector<float>().swap(distmap_);
63+
comparator_.DiffmapOpsinDynamicsImage(rgb0, rgb, distmap_);
5664
distance_ = ::butteraugli::ButteraugliScoreFromDiffmap(distmap_);
5765
GUETZLI_LOG(stats_, " BA[100.00%%] D[%6.4f]", distance_);
5866
}
5967

6068
void ButteraugliComparator::StartBlockComparisons() {
6169
std::vector<std::vector<float> > dummy(3);
62-
::butteraugli::Mask(rgb_linear_pregamma_, rgb_linear_pregamma_,
70+
std::vector<std::vector<float> > rgb0 =
71+
ComputeOpsinDynamicsImage(width_, height_, rgb_orig_);
72+
::butteraugli::Mask(rgb0, rgb0,
6373
width_, height_,
6474
&mask_xyz_, &dummy);
6575
}

‎guetzli/butteraugli_comparator.h

-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class ButteraugliComparator : public Comparator {
7171
int block_y_;
7272
int factor_x_;
7373
int factor_y_;
74-
std::vector<std::vector<float>> rgb_linear_pregamma_;
7574
std::vector<std::vector<float>> mask_xyz_;
7675
std::vector<std::vector<std::vector<float>>> per_block_pregamma_;
7776
::butteraugli::ButteraugliComparator comparator_;

‎guetzli/guetzli.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ constexpr int kDefaultJPEGQuality = 95;
3535

3636
// An upper estimate of memory usage of Guetzli. The bound is
3737
// max(kLowerMemusaeMB * 1<<20, pixel_count * kBytesPerPixel)
38-
constexpr int kBytesPerPixel = 125;
38+
constexpr int kBytesPerPixel = 110;
3939
constexpr int kLowestMemusageMB = 100; // in MB
4040

4141
constexpr int kDefaultMemlimitMB = 6000; // in MB

‎guetzli/processor.cc

-5
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ void Processor::MaybeOutput(const std::string& encoded_jpg) {
141141
GUETZLI_LOG(stats_, " Score[%.4f]", score);
142142
if (score < final_output_->score || final_output_->score < 0) {
143143
final_output_->jpeg_data = encoded_jpg;
144-
final_output_->distmap = comparator_->distmap();
145-
final_output_->distmap_aggregate = comparator_->distmap_aggregate();
146144
final_output_->score = score;
147145
GUETZLI_LOG(stats_, " (*)");
148146
}
@@ -823,9 +821,6 @@ bool Processor::ProcessJpegData(const Params& params, const JPEGData& jpg_in,
823821
if (comparator_ == nullptr) {
824822
GUETZLI_LOG(stats, " <image too small for Butteraugli>\n");
825823
final_output_->jpeg_data = encoded_jpg;
826-
final_output_->distmap =
827-
std::vector<float>(jpg_in.width * jpg_in.height, 0.0);
828-
final_output_->distmap_aggregate = 0;
829824
final_output_->score = encoded_jpg.size();
830825
// Butteraugli doesn't work with images this small.
831826
return true;

‎guetzli/processor.h

-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ bool Process(const Params& params, ProcessStats* stats,
4242

4343
struct GuetzliOutput {
4444
std::string jpeg_data;
45-
std::vector<float> distmap;
46-
double distmap_aggregate;
4745
double score;
4846
};
4947

‎third_party/butteraugli/butteraugli/butteraugli.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -1023,14 +1023,14 @@ void CalculateDiffmap(const size_t xsize, const size_t ysize,
10231023
}
10241024

10251025
void ButteraugliComparator::DiffmapOpsinDynamicsImage(
1026-
const std::vector<std::vector<float>> &xyb0_arg,
1026+
std::vector<std::vector<float>> &xyb0,
10271027
std::vector<std::vector<float>> &xyb1,
10281028
std::vector<float> &result) {
10291029
if (xsize_ < 8 || ysize_ < 8) return;
1030-
auto xyb0 = xyb0_arg;
10311030
{
1031+
auto xyb0_c = xyb0;
10321032
auto xyb1_c = xyb1;
1033-
MaskHighIntensityChange(xsize_, ysize_, xyb0_arg, xyb1_c, xyb0, xyb1);
1033+
MaskHighIntensityChange(xsize_, ysize_, xyb0_c, xyb1_c, xyb0, xyb1);
10341034
}
10351035
assert(8 <= xsize_);
10361036
for (int i = 0; i < 3; i++) {

‎third_party/butteraugli/butteraugli/butteraugli.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class ButteraugliComparator {
4545

4646
// Computes the butteraugli map between xyb0 and xyb1 and updates result.
4747
// Both xyb0 and xyb1 are in opsin-dynamics space.
48-
// NOTE: The xyb1 image is mutated by this function in-place.
49-
void DiffmapOpsinDynamicsImage(const std::vector<std::vector<float>> &xyb0,
48+
// NOTE: The xyb0 and xyb1 images are mutated by this function in-place.
49+
void DiffmapOpsinDynamicsImage(std::vector<std::vector<float>> &xyb0,
5050
std::vector<std::vector<float>> &xyb1,
5151
std::vector<float> &result);
5252

0 commit comments

Comments
 (0)