aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc')
-rw-r--r--roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc197
1 files changed, 197 insertions, 0 deletions
diff --git a/roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc b/roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc
new file mode 100644
index 000000000..b0192a217
--- /dev/null
+++ b/roms/edk2/BaseTools/Source/C/BrotliCompress/brotli/research/draw_histogram.cc
@@ -0,0 +1,197 @@
+/* Copyright 2016 Google Inc. All Rights Reserved.
+ Author: zip753@gmail.com (Ivan Nikulin)
+
+ Distributed under MIT license.
+ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+*/
+
+/* Backward reference visualization tool. Accepts file with backward references
+ as an input and produces PGM image with histogram of those references. */
+
+#include <algorithm> /* min */
+#include <cassert>
+#include <cstring> /* memset */
+#include <cmath> /* log, round */
+#include <cstdio> /* fscanf, fprintf */
+#include <cstdint>
+
+#include <gflags/gflags.h>
+using gflags::ParseCommandLineFlags;
+
+#include "./read_dist.h"
+
+DEFINE_int32(height, 1000, "Height of the resulting histogam.");
+DEFINE_int32(width, 8000, "Width of the resulting histogam.");
+DEFINE_int32(size, 1e8, "Size of the compressed file.");
+DEFINE_int32(brotli_window, -1, "Size of brotli window in bits.");
+DEFINE_uint64(min_distance, 0, "Minimum distance.");
+DEFINE_uint64(max_distance, 1 << 30, "Maximum distance.");
+DEFINE_bool(with_copies, false, "True if input contains copy length.");
+DEFINE_bool(simple, false, "True if using only black and white pixels.");
+DEFINE_bool(linear, false, "True if using linear distance mapping.");
+DEFINE_uint64(skip, 0, "Number of bytes to skip.");
+
+inline double DistanceTransform(double x) {
+ static bool linear = FLAGS_linear;
+ if (linear) {
+ return x;
+ } else {
+ /* Using log^2 scale because log scale produces big white gap at the bottom
+ of image. */
+ return log(x) * log(x);
+ }
+}
+
+/* Mapping pixel density on arc function to increase contrast. */
+inline double DensityTransform(double x) {
+ double z = 255 - x;
+ return sqrt(255 * 255 - z * z);
+}
+
+inline int GetMaxDistance() {
+ return FLAGS_max_distance;
+}
+
+void AdjustPosition(int* pos) {
+ static uint32_t offset = 0;
+ static int last = 0;
+ static uint32_t window_size = (1 << FLAGS_brotli_window);
+ assert(*pos >= 0 && *pos < window_size);
+ if (*pos < last) {
+ offset += window_size;
+ }
+ last = *pos;
+ *pos += offset;
+}
+
+void BuildHistogram(FILE* fin, int** histo) {
+ int height = FLAGS_height;
+ int width = FLAGS_width;
+ int skip = FLAGS_skip;
+ size_t min_distance = FLAGS_min_distance;
+
+ printf("height = %d, width = %d\n", height, width);
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ histo[i][j] = 0;
+ }
+ }
+
+ int max_pos = FLAGS_size - skip;
+ double min_dist = min_distance > 0 ? DistanceTransform(min_distance) : 0;
+ double max_dist = DistanceTransform(GetMaxDistance()) - min_dist;
+ int copy, pos, distance, x, y;
+ double dist;
+ while (ReadBackwardReference(fin, &copy, &pos, &distance)) {
+ if (pos == -1) continue; // In case when only insert is present.
+ if (distance < min_distance || distance >= GetMaxDistance()) continue;
+ if (FLAGS_brotli_window != -1) {
+ AdjustPosition(&pos);
+ }
+ if (pos >= skip && distance <= pos) {
+ pos -= skip;
+ if (pos >= max_pos) break;
+ dist = DistanceTransform(static_cast<double>(distance)) - min_dist;
+
+ x = std::min(static_cast<int>(round(dist / max_dist * height)),
+ height - 1);
+ y = 1ul * pos * width / max_pos;
+ if (!(y >= 0 && y < width)) {
+ printf("pos = %d, max_pos = %d, y = %d\n", pos, max_pos, y);
+ assert(y >= 0 && y < width);
+ }
+
+ if (FLAGS_with_copies) {
+ int right = 1ul * (pos + copy - 1) * width / max_pos;
+ if (right < 0) {
+ printf("pos = %d, distance = %d, copy = %d, y = %d, right = %d\n",
+ pos, distance, copy, y, right);
+ assert(right >= 0);
+ }
+ if (y == right) {
+ histo[x][y] += copy;
+ } else {
+ int pos2 = static_cast<int>(ceil(1.0 * (y + 1) * max_pos / width));
+ histo[x][y] += pos2 - pos;
+ for (int i = y + 1; i < right && i < width; ++i) {
+ histo[x][i] += max_pos / width; // Sometimes 1 more, but who cares.
+ }
+ // Make sure the match doesn't go beyond the image.
+ if (right < width) {
+ pos2 = static_cast<int>(ceil(1.0 * right * max_pos / width));
+ histo[x][right] += pos + copy - 1 - pos2 + 1;
+ }
+ }
+ } else {
+ histo[x][y]++;
+ }
+ }
+ }
+}
+
+void ConvertToPixels(int** histo, uint8_t** pixel) {
+ int height = FLAGS_height;
+ int width = FLAGS_width;
+
+ int maxs = 0;
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ if (maxs < histo[i][j]) maxs = histo[i][j];
+ }
+ }
+
+ bool simple = FLAGS_simple;
+ double max_histo = static_cast<double>(maxs);
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ if (simple) {
+ pixel[i][j] = histo[i][j] > 0 ? 0 : 255;
+ } else {
+ pixel[i][j] = static_cast<uint8_t>(
+ 255 - DensityTransform(histo[i][j] / max_histo * 255));
+ }
+ }
+ }
+}
+
+void DrawPixels(uint8_t** pixel, FILE* fout) {
+ int height = FLAGS_height;
+ int width = FLAGS_width;
+
+ fprintf(fout, "P5\n%d %d\n255\n", width, height);
+ for (int i = height - 1; i >= 0; i--) {
+ fwrite(pixel[i], 1, width, fout);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ ParseCommandLineFlags(&argc, &argv, true);
+ if (argc != 3) {
+ printf("usage: draw_histogram.cc data output_file\n");
+ return 1;
+ }
+
+ int height = FLAGS_height;
+ int width = FLAGS_width;
+
+ FILE* fin = fopen(argv[1], "r");
+ FILE* fout = fopen(argv[2], "wb");
+
+ uint8_t** pixel = new uint8_t*[height];
+ int** histo = new int*[height];
+ for (int i = 0; i < height; i++) {
+ pixel[i] = new uint8_t[width];
+ histo[i] = new int[width];
+ }
+
+ BuildHistogram(fin, histo);
+ fclose(fin);
+
+ ConvertToPixels(histo, pixel);
+
+ DrawPixels(pixel, fout);
+ fclose(fout);
+
+ return 0;
+}