From 93f5cd0ba4b20cbd8e60278249f49709119fb2e6 Mon Sep 17 00:00:00 2001 From: murat Date: Sat, 8 Aug 2026 04:37:38 +0300 Subject: [PATCH] optimization: streamline image loading and remove pixel vector - Read file once and decode from memory using stbi_load_from_memory - Add guard for files smaller than 8 bytes - Remove std::vector and accumulate histogram in downsample loop --- main.cpp | 85 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/main.cpp b/main.cpp index a171394..2729100 100644 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include using std::cout; @@ -15,10 +16,6 @@ namespace fs = std::filesystem; bool is_jpeg(const unsigned char* buf); bool is_png(const unsigned char* buf); -struct Pixel { - unsigned char r, g, b; -}; - struct Bucket { long r = 0; long g = 0; @@ -62,22 +59,30 @@ int main(int argc, char *argv[]) { return 1; } - unsigned char header[8]; - file.read(reinterpret_cast(header), 8); + // Read the file once; detect the format from the buffer and decode from + // memory so the image is never read from disk a second time. + std::vector buffer((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + if (buffer.size() < 8) { + cout << "File is too small to be a valid image!\n"; + return 1; + } + const unsigned char* header = buffer.data(); if (is_png(header)) { cout << "PNG file detected!\n"; } else if (is_jpeg(header)) { cout << "JPEG file detected!\n"; } else { - cout << "Unkown image file format!\n"; + cout << "Unknown image file format!\n"; return 1; } int width, height, channels; - unsigned char* data = stbi_load( - argv[1], + unsigned char* data = stbi_load_from_memory( + buffer.data(), + static_cast(buffer.size()), &width, &height, &channels, @@ -97,46 +102,42 @@ int main(int argc, char *argv[]) { cout << "Channels: " << channels << "\n"; cout << "**********\n"; - std::vector samples; + std::unordered_map hist; int step = 10; //downsample rate - for (int y = 0; y< height; y += step) { - for (int x = 0; x < width; x+= step) { + long sampled = 0; + for (int y = 0; y < height; y += step) { + for (int x = 0; x < width; x += step) { int idx = (y * width + x) * 3; - Pixel p; - p.r = data[idx]; - p.g = data[idx + 1]; - p.b = data[idx + 2]; - samples.push_back(p); + unsigned char r = data[idx]; + unsigned char g = data[idx + 1]; + unsigned char b = data[idx + 2]; + sampled++; + + int brightness = r + g + b; + if (brightness < 60) continue; //filtering out dark pixels + + int minc = std::min({r, g, b}); + int maxc = std::max({r, g, b}); + if (maxc - minc < 10) continue; //filtering out low saturation + //(gray) colors + + int rq = r / 16; + int gq = g / 16; + int bq = b / 16; + + int key = (rq << 8) | (gq << 4) | bq; + + auto& bucket = hist[key]; + bucket.r += r; + bucket.g += g; + bucket.b += b; + bucket.count++; } } - cout << "Sampled pixels: " << samples.size() << "\n"; - - std::unordered_map hist; - - for (auto& p : samples) { - int brightness = p.r + p.g + p.b; - if (brightness < 60) continue; //filtering out dark pixels - - int minc = std::min({p.r, p.g, p.b}); - int maxc = std::max({p.r, p.g, p.b}); - if (maxc - minc < 10) continue; //filtering out low saturation - //(gray) colors - - int rq = p.r / 16; - int gq = p.g / 16; - int bq = p.b / 16; - - int key = (rq << 8) | (gq << 4) | bq; - - auto& bucket = hist[key]; - bucket.r += p.r; - bucket.g += p.g; - bucket.b += p.b; - bucket.count ++; - } + cout << "Sampled pixels: " << sampled << "\n"; std::vector buckets;