1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
5
6 #include "lib/jxl/aux_out.h"
7
8 #include <stdint.h>
9
10 #include <numeric> // accumulate
11
12 #include "lib/jxl/aux_out_fwd.h"
13 #include "lib/jxl/enc_bit_writer.h"
14
15 namespace jxl {
16
Print(size_t num_inputs) const17 void AuxOut::Print(size_t num_inputs) const {
18 if (num_inputs == 0) return;
19
20 LayerTotals all_layers;
21 for (size_t i = 0; i < layers.size(); ++i) {
22 all_layers.Assimilate(layers[i]);
23 }
24
25 printf("Average butteraugli iters: %10.2f\n",
26 num_butteraugli_iters * 1.0 / num_inputs);
27
28 for (size_t i = 0; i < layers.size(); ++i) {
29 if (layers[i].total_bits != 0) {
30 printf("Total layer bits %-10s\t", LayerName(i));
31 printf("%10f%%", 100.0 * layers[i].total_bits / all_layers.total_bits);
32 layers[i].Print(num_inputs);
33 }
34 }
35 printf("Total image size ");
36 all_layers.Print(num_inputs);
37
38 const uint32_t dc_pred_total =
39 std::accumulate(dc_pred_usage.begin(), dc_pred_usage.end(), 0u);
40 const uint32_t dc_pred_total_xb =
41 std::accumulate(dc_pred_usage_xb.begin(), dc_pred_usage_xb.end(), 0u);
42 if (dc_pred_total + dc_pred_total_xb != 0) {
43 printf("\nDC pred Y XB:\n");
44 for (size_t i = 0; i < dc_pred_usage.size(); ++i) {
45 printf(" %6u (%5.2f%%) %6u (%5.2f%%)\n", dc_pred_usage[i],
46 100.0 * dc_pred_usage[i] / dc_pred_total, dc_pred_usage_xb[i],
47 100.0 * dc_pred_usage_xb[i] / dc_pred_total_xb);
48 }
49 }
50
51 size_t total_blocks = 0;
52 size_t total_positions = 0;
53 if (total_blocks != 0 && total_positions != 0) {
54 printf("\n\t\t Blocks\t\tPositions\t\t\tBlocks/Position\n");
55 printf(" Total:\t\t %7zu\t\t %7zu \t\t\t%10f%%\n\n", total_blocks,
56 total_positions, 100.0 * total_blocks / total_positions);
57 }
58 }
59
DumpCoeffImage(const char * label,const Image3S & coeff_image) const60 void AuxOut::DumpCoeffImage(const char* label,
61 const Image3S& coeff_image) const {
62 JXL_ASSERT(coeff_image.xsize() % 64 == 0);
63 Image3S reshuffled(coeff_image.xsize() / 8, coeff_image.ysize() * 8);
64 for (size_t c = 0; c < 3; c++) {
65 for (size_t y = 0; y < coeff_image.ysize(); y++) {
66 for (size_t x = 0; x < coeff_image.xsize(); x += 64) {
67 for (size_t i = 0; i < 64; i++) {
68 reshuffled.PlaneRow(c, 8 * y + i / 8)[x / 8 + i % 8] =
69 coeff_image.PlaneRow(c, y)[x + i];
70 }
71 }
72 }
73 }
74 DumpImage(label, reshuffled);
75 }
76
ReclaimAndCharge(BitWriter * JXL_RESTRICT writer,BitWriter::Allotment * JXL_RESTRICT allotment,size_t layer,AuxOut * JXL_RESTRICT aux_out)77 void ReclaimAndCharge(BitWriter* JXL_RESTRICT writer,
78 BitWriter::Allotment* JXL_RESTRICT allotment,
79 size_t layer, AuxOut* JXL_RESTRICT aux_out) {
80 size_t used_bits, unused_bits;
81 allotment->PrivateReclaim(writer, &used_bits, &unused_bits);
82
83 #if 0
84 printf("Layer %s bits: max %zu used %zu unused %zu\n", LayerName(layer),
85 allotment->MaxBits(), used_bits, unused_bits);
86 #endif
87
88 // This may be a nested call with aux_out == null. Whenever we know that
89 // aux_out is null, we can call ReclaimUnused directly.
90 if (aux_out != nullptr) {
91 aux_out->layers[layer].total_bits += used_bits;
92 aux_out->layers[layer].histogram_bits += allotment->HistogramBits();
93 }
94 }
95
96 } // namespace jxl
97