diff --git a/tests/g2chromatic.cpp b/tests/g2chromatic.cpp index 6ff20e9..08fdef4 100644 --- a/tests/g2chromatic.cpp +++ b/tests/g2chromatic.cpp @@ -5,161 +5,215 @@ #include #include "../util/grid/grid2.hpp" #include "../util/output/aviwriter.hpp" +#include "../util/timing_decorator.cpp" -int main() { - // Create a Grid2 instance - Grid2 grid; +struct AnimationConfig { + int width = 512; + int height = 512; + int totalFrames = 240; + float fps = 30.0f; + int numSeeds = 1; +}; + +bool initializeGrid(Grid2& grid, const AnimationConfig& config) { + TIME_FUNCTION; + std::cout << "Initializing grayscale grid..." << std::endl; - // Grid dimensions - const int width = 100; - const int height = 100; - const int totalFrames = 60; // 2 seconds at 30fps - - std::cout << "Creating chromatic transformation animation..." << std::endl; - - // Initialize with grayscale gradient - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - float gradient = (x + y) / float(width + height - 2); + for (int y = 1; y < config.height; ++y) { + for (int x = 1; x < config.width; ++x) { + float gradient = (x + y) / float(config.width + config.height - 2); Vec2 position(static_cast(x), static_cast(y)); Vec4 color(gradient, gradient, gradient, 1.0f); grid.addObject(position, color, 1.0f); } } - std::cout << "Initial grayscale grid created with " << width * height << " objects" << std::endl; - - // Random number generation for seed points + std::cout << "Grayscale grid created with " << config.width * config.height << " objects" << std::endl; + return true; +} + +std::pair, std::vector> generateSeedPoints(const AnimationConfig& config) { + TIME_FUNCTION; std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution<> xDist(0, width - 1); - std::uniform_int_distribution<> yDist(0, height - 1); + std::uniform_int_distribution<> xDist(0, config.width - 1); + std::uniform_int_distribution<> yDist(0, config.height - 1); std::uniform_real_distribution<> colorDist(0.2f, 0.8f); - // Generate multiple seed points for more interesting patterns - const int numSeeds = 1; std::vector seedPoints; std::vector seedColors; - for (int i = 0; i < numSeeds; ++i) { + for (int i = 0; i < config.numSeeds; ++i) { seedPoints.emplace_back(xDist(gen), yDist(gen)); seedColors.emplace_back(colorDist(gen), colorDist(gen), colorDist(gen), colorDist(gen)); } - std::cout << "Generated " << numSeeds << " seed points for color propagation" << std::endl; + std::cout << "Generated " << config.numSeeds << " seed points for color propagation" << std::endl; + return {seedPoints, seedColors}; +} + +void applyDirectionalColorInfluence(Vec4& color, const Vec4& seedColor, float influence, + float progress, float angle) { + //TIME_FUNCTION; + if (std::abs(angle) < M_PI / 4.0f) { // Right - affect alpha + color.a = std::fmod(color.a + seedColor.a * influence * progress, 1.0f); + } else if (std::abs(angle) > 3.0f * M_PI / 4.0f) { // Left - affect blue + color.b = std::fmod(color.b + seedColor.b * influence * progress, 1.0f); + } else if (angle > 0) { // Below - affect green + color.g = std::fmod(color.g + seedColor.g * influence * progress, 1.0f); + } else { // Above - affect red + color.r = std::fmod(color.r + seedColor.r * influence * progress, 1.0f); + } +} + +Vec4 calculateInfluencedColor(const Vec2& position, const Vec4& originalColor, float progress, + const std::vector& seedPoints, const std::vector& seedColors, + const AnimationConfig& config) { + //TIME_FUNCTION; + Vec4 newColor = originalColor; - // Create frames for AVI + float maxDistance = std::max(config.width, config.height) * 0.6f; + for (int s = 0; s < config.numSeeds; ++s) { + float distance = position.distance(seedPoints[s]); + float influence = std::max(0.0f, 1.0f - (distance / maxDistance)); + + Vec2 direction = position - seedPoints[s]; + float angle = std::atan2(direction.y, direction.x); + + applyDirectionalColorInfluence(newColor, seedColors[s], influence, progress, angle); + } + + return newColor.clampColor(); +} + +void updateColorsForFrame(Grid2& grid, float progress, const std::vector& seedPoints, + const std::vector& seedColors, const AnimationConfig& config) { + TIME_FUNCTION; + + grid.bulkUpdateColors([&](size_t id, const Vec2& pos, const Vec4& currentColor) { + return calculateInfluencedColor(pos, currentColor, progress, seedPoints, seedColors, config); + }); +} + +std::vector convertFrameToBGR(Grid2& grid, const AnimationConfig& config) { + TIME_FUNCTION; + int frameWidth, frameHeight; + std::vector bgrData; + grid.getGridRegionAsBGR(Vec2(0,0),Vec2(512,512), frameWidth, frameHeight, bgrData); + //grid.getGridRegionAsRGB(0.0f,0.0f,512.0f,512.0f,frameWidth,frameHeight,rgbData); + + std::vector bgrFrame(frameWidth * frameHeight * 3); + #pragma omp parallel for + for (int i = 0; i < frameWidth * frameHeight; ++i) { + int r = std::clamp(bgrData[i * 3 + 2], 0, 255); + int g = std::clamp(bgrData[i * 3 + 1], 0, 255); + int b = std::clamp(bgrData[i * 3], 0, 255); + + bgrFrame[i * 3] = static_cast(b); + bgrFrame[i * 3 + 1] = static_cast(g); + bgrFrame[i * 3 + 2] = static_cast(r); + } + + return bgrFrame; +} + +bool validateFrameSize(const std::vector& frame, const AnimationConfig& config) { + return frame.size() == config.width * config.height * 3; +} + +std::vector> createAnimationFrames(Grid2& grid, + const std::vector& seedPoints, + const std::vector& seedColors, + const AnimationConfig& config) { + TIME_FUNCTION; std::vector> frames; - for (int frame = 0; frame < totalFrames; ++frame) { - std::cout << "Processing frame " << frame + 1 << "/" << totalFrames << std::endl; + for (int frame = 0; frame < config.totalFrames; ++frame) { + std::cout << "Processing frame " << frame + 1 << "/" << config.totalFrames << std::endl; - // Apply color propagation based on frame progress - float progress = static_cast(frame) / (totalFrames - 1); + float progress = static_cast(frame) / (config.totalFrames - 1); + updateColorsForFrame(grid, progress, seedPoints, seedColors, config); - // Update colors based on seed propagation - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - Vec2 currentPos(x, y); - size_t id = grid.getIndicesAt(currentPos)[0]; // Assuming one object per position - Vec4 originalColor = grid.getColor(id); - - Vec4 newColor = originalColor; - - // For each seed point, calculate influence - for (int s = 0; s < numSeeds; ++s) { - float distance = currentPos.distance(seedPoints[s]); - float maxDistance = std::max(width, height) * 0.6f; - float influence = std::max(0.0f, 1.0f - (distance / maxDistance)); - - // Apply influence based on relative position to seed - Vec2 direction = currentPos - seedPoints[s]; - float angle = std::atan2(direction.y, direction.x); - - // Different color channels respond to different directions - if (std::abs(angle) < M_PI / 4.0f) { // Right - affect alpha - newColor.a = std::fmod(newColor.a + seedColors[s].a * influence * progress, 1.0f); - } else if (std::abs(angle) > 3.0f * M_PI / 4.0f) { // Left - affect blue - newColor.b = std::fmod(newColor.b + seedColors[s].b * influence * progress, 1.0f); - } else if (angle > 0) { // Below - affect green - newColor.g = std::fmod(newColor.g + seedColors[s].g * influence * progress, 1.0f); - } else { // Above - affect red - newColor.r = std::fmod(newColor.r + seedColors[s].r * influence * progress, 1.0f); - } - } - - // Clamp colors to valid range - newColor = newColor.clampColor(); - grid.setColor(id, newColor); - } - } + auto bgrFrame = convertFrameToBGR(grid, config); - // Get current frame as RGB data - int frameWidth, frameHeight; - std::vector rgbData; - grid.getGridAsRGB(frameWidth, frameHeight, rgbData); - - // Debug output to check frame dimensions - std::cout << "Frame " << frame << ": " << frameWidth << "x" << frameHeight - << ", RGB data size: " << rgbData.size() << std::endl; - - // Convert to BGR format for AVI and ensure proper 8-bit values - std::vector bgrFrame(frameWidth * frameHeight * 3); - #pragma omp parallel for - for (int i = 0; i < frameWidth * frameHeight; ++i) { - // Ensure values are in 0-255 range and convert RGB to BGR - int r = std::clamp(rgbData[i * 3], 0, 255); - int g = std::clamp(rgbData[i * 3 + 1], 0, 255); - int b = std::clamp(rgbData[i * 3 + 2], 0, 255); - - bgrFrame[i * 3] = static_cast(b); // B - bgrFrame[i * 3 + 1] = static_cast(g); // G - bgrFrame[i * 3 + 2] = static_cast(r); // R - } - - // Verify frame size matches expected - if (bgrFrame.size() != width * height * 3) { - std::cerr << "ERROR: Frame size mismatch! Expected: " << width * height * 3 - << ", Got: " << bgrFrame.size() << std::endl; - return 1; - } + // if (!validateFrameSize(bgrFrame, config)) { + // std::cerr << "ERROR: Frame size mismatch in frame " << frame << std::endl; + // continue; + // } frames.push_back(bgrFrame); } - // Save as AVI + return frames; +} + +void printSuccessMessage(const std::string& filename, + const std::vector& seedPoints, + const std::vector& seedColors, + const AnimationConfig& config) { + std::cout << "\nSuccessfully saved chromatic transformation animation to: " << filename << std::endl; + std::cout << "Video details:" << std::endl; + std::cout << " - Dimensions: " << config.width << " x " << config.height << std::endl; + std::cout << " - Frames: " << config.totalFrames << " (" + << config.totalFrames/config.fps << " seconds at " << config.fps << "fps)" << std::endl; + std::cout << " - Seed points: " << config.numSeeds << std::endl; + + std::cout << "\nSeed points used:" << std::endl; + for (int i = 0; i < config.numSeeds; ++i) { + std::cout << " Seed " << i + 1 << ": Position " << seedPoints[i] + << ", Color " << seedColors[i].toColorString() << std::endl; + } + FunctionTimer::printStats(FunctionTimer::Mode::ENHANCED); +} + +void printErrorMessage(const std::vector>& frames, const AnimationConfig& config) { + std::cerr << "Failed to save AVI file!" << std::endl; + std::cerr << "Debug info:" << std::endl; + std::cerr << " - Frames count: " << frames.size() << std::endl; + if (!frames.empty()) { + std::cerr << " - First frame size: " << frames[0].size() << std::endl; + std::cerr << " - Expected frame size: " << config.width * config.height * 3 << std::endl; + } + std::cerr << " - Width: " << config.width << ", Height: " << config.height << std::endl; +} + +bool saveAnimation(const std::vector>& frames, const std::vector& seedPoints, + const std::vector& seedColors, const AnimationConfig& config) { + TIME_FUNCTION; std::string filename = "output/chromatic_transformation.avi"; std::cout << "Attempting to save AVI file: " << filename << std::endl; - std::cout << "Frames to save: " << frames.size() << std::endl; - std::cout << "Frame dimensions: " << width << "x" << height << std::endl; - bool success = AVIWriter::saveAVI(filename, frames, width, height, 30.0f); + bool success = AVIWriter::saveAVI(filename, frames, config.width, config.height, config.fps); if (success) { - std::cout << "\nSuccessfully saved chromatic transformation animation to: " << filename << std::endl; - std::cout << "Video details:" << std::endl; - std::cout << " - Dimensions: " << width << " x " << height << std::endl; - std::cout << " - Frames: " << totalFrames << " (2 seconds at 30fps)" << std::endl; - std::cout << " - Seed points: " << numSeeds << std::endl; - - // Print seed point information - std::cout << "\nSeed points used:" << std::endl; - for (int i = 0; i < numSeeds; ++i) { - std::cout << " Seed " << i + 1 << ": Position " << seedPoints[i] - << ", Color " << seedColors[i].toColorString() << std::endl; - } + printSuccessMessage(filename, seedPoints, seedColors, config); + return true; } else { - std::cerr << "Failed to save AVI file!" << std::endl; - - // Additional debugging information - std::cerr << "Debug info:" << std::endl; - std::cerr << " - Frames count: " << frames.size() << std::endl; - if (!frames.empty()) { - std::cerr << " - First frame size: " << frames[0].size() << std::endl; - std::cerr << " - Expected frame size: " << width * height * 3 << std::endl; - } - std::cerr << " - Width: " << width << ", Height: " << height << std::endl; - + printErrorMessage(frames, config); + return false; + } +} + +int main() { + std::cout << "Creating chromatic transformation animation..." << std::endl; + + // Configuration + AnimationConfig config; + + // Initialize grid + Grid2 grid; + if (!initializeGrid(grid, config)) { + return 1; + } + + // Generate seed points + auto [seedPoints, seedColors] = generateSeedPoints(config); + + // Create animation frames + auto frames = createAnimationFrames(grid, seedPoints, seedColors, config); + + // Save animation + if (!saveAnimation(frames, seedPoints, seedColors, config)) { return 1; } diff --git a/util/grid/grid2.hpp b/util/grid/grid2.hpp index e1125e0..d16173f 100644 --- a/util/grid/grid2.hpp +++ b/util/grid/grid2.hpp @@ -3,6 +3,7 @@ #include "../vectorlogic/vec2.hpp" #include "../vectorlogic/vec4.hpp" +#include "../timing_decorator.hpp" #include #include #include @@ -123,6 +124,55 @@ public: } } + std::vector getAllObjectIds() const { + std::vector ids; + for (const auto& pair : positions) { + ids.push_back(pair.first); + } + // Sort by ID to ensure consistent order + std::sort(ids.begin(), ids.end()); + return ids; + } + + void bulkUpdateColors(const std::function& colorFunc) { + TIME_FUNCTION; + + // Convert to contiguous storage for better performance + std::vector> objectData; + objectData.reserve(positions.size()); + + // Single pass to collect all data + for (const auto& posPair : positions) { + size_t id = posPair.first; + auto colorIt = colors.find(id); + if (colorIt != colors.end()) { + objectData.emplace_back(id, posPair.second, colorIt->second); + } + } + + // Parallel color computation + std::vector> updates; + updates.resize(objectData.size()); + + #pragma omp parallel for + for (size_t i = 0; i < objectData.size(); ++i) { + const auto& [id, pos, currentColor] = objectData[i]; + Vec4 newColor = colorFunc(id, pos, currentColor); + updates[i] = {id, newColor}; + } + + // Batch update colors - much more efficient + for (const auto& update : updates) { + // Directly update existing entry instead of erase/insert + auto it = colors.find(update.first); + if (it != colors.end()) { + // If multimap doesn't support direct modification, we need to replace + // For better performance, consider changing data structure + const_cast(it->second) = update.second; + } + } + } + //other bool hasObject(size_t id) const { return positions.find(id) != positions.end(); @@ -151,6 +201,7 @@ public: } std::vector getIndicesAt(const Vec2& position, float radius = 0.0f) const { + TIME_FUNCTION; std::vector result; if (radius <= 0.0f) { @@ -176,6 +227,7 @@ public: } void getBoundingBox(Vec2& minCorner, Vec2& maxCorner) const { + TIME_FUNCTION; if (positions.empty()) { minCorner = Vec2(0.0f, 0.0f); maxCorner = Vec2(0.0f, 0.0f); @@ -199,55 +251,12 @@ public: } //to picture - void getGridAsRGB(int& width, int& height, std::vector& rgbData) const { - Vec2 minCorner, maxCorner; - getBoundingBox(minCorner, maxCorner); + void getGridRegionAsRGB(const Vec2& minCorner, const Vec2& maxCorner, + int& width, int& height, std::vector& rgbData) const { + TIME_FUNCTION; - // Calculate grid dimensions (adding 1 to include both ends) - width = static_cast(std::ceil(maxCorner.x - minCorner.x)) ; - height = static_cast(std::ceil(maxCorner.y - minCorner.y)) ; - - // Initialize with black (0,0,0) - rgbData.resize(width * height * 3, 0); - - // Fill the grid with object colors, accounting for sizes - for (const auto& posPair : positions) { - size_t id = posPair.first; - const Vec2& pos = posPair.second; - float size = getSize(id); - const Vec4& color = getColor(id); - - // Calculate the bounding box of this object in grid coordinates - float halfSize = size * 0.5f; - int minGridX = static_cast(std::floor((pos.x - halfSize - minCorner.x))); - int minGridY = static_cast(std::floor((pos.y - halfSize - minCorner.y))); - int maxGridX = static_cast(std::ceil((pos.x + halfSize - minCorner.x))); - int maxGridY = static_cast(std::ceil((pos.y + halfSize - minCorner.y))); - - // Clamp to grid boundaries - minGridX = std::max(0, minGridX); - minGridY = std::max(0, minGridY); - maxGridX = std::min(width - 1, maxGridX); - maxGridY = std::min(height - 1, maxGridY); - - // Fill all pixels within the object's size - for (int y = minGridY; y <= maxGridY; ++y) { - for (int x = minGridX; x <= maxGridX; ++x) { - int index = (y * width + x) * 3; - - // Convert float color [0,1] to int [0,255] - rgbData[index] = static_cast(color.r * 255); - rgbData[index + 1] = static_cast(color.g * 255); - rgbData[index + 2] = static_cast(color.b * 255); - } - } - } - } - - void getRegionAsRGB(float minX, float minY, float maxX, float maxY, - int& width, int& height, std::vector& rgbData) const { // Ensure valid region - if (minX >= maxX || minY >= maxY) { + if (minCorner.x >= maxCorner.x || minCorner.y >= maxCorner.y) { width = 0; height = 0; rgbData.clear(); @@ -255,10 +264,10 @@ public: } // Calculate grid dimensions - width = static_cast(std::ceil(maxX - minX)); - height = static_cast(std::ceil(maxY - minY)); + width = static_cast(std::ceil(maxCorner.x - minCorner.x)); + height = static_cast(std::ceil(maxCorner.y - minCorner.y)); - // Initialize with black (0,0,0) + // Initialize with black (0,0,0) in BGR format rgbData.resize(width * height * 3, 0); // Fill the grid with object colors in the region, accounting for sizes @@ -276,12 +285,14 @@ public: float objMaxY = pos.y + halfSize; // Check if object overlaps with the region - if (objMaxX >= minX && objMinX <= maxX && objMaxY >= minY && objMinY <= maxY) { + if (objMaxX >= minCorner.x && objMinX <= maxCorner.x && + objMaxY >= minCorner.y && objMinY <= maxCorner.y) { + // Calculate overlapping region in grid coordinates - int minGridX = static_cast(std::floor(std::max(objMinX, minX) - minX)); - int minGridY = static_cast(std::floor(std::max(objMinY, minY) - minY)); - int maxGridX = static_cast(std::ceil(std::min(objMaxX, maxX) - minX)); - int maxGridY = static_cast(std::ceil(std::min(objMaxY, maxY) - minY)); + int minGridX = static_cast(std::floor(std::max(objMinX, minCorner.x) - minCorner.x)); + int minGridY = static_cast(std::floor(std::max(objMinY, minCorner.y) - minCorner.y)); + int maxGridX = static_cast(std::ceil(std::min(objMaxX, maxCorner.x) - minCorner.x)); + int maxGridY = static_cast(std::ceil(std::min(objMaxY, maxCorner.y) - minCorner.y)); // Clamp to grid boundaries minGridX = std::max(0, minGridX); @@ -289,25 +300,117 @@ public: maxGridX = std::min(width - 1, maxGridX); maxGridY = std::min(height - 1, maxGridY); - // Fill all pixels within the object's overlapping region + // Fill all pixels within the object's overlapping region in BGR format for (int y = minGridY; y <= maxGridY; ++y) { for (int x = minGridX; x <= maxGridX; ++x) { int index = (y * width + x) * 3; - // Convert float color [0,1] to int [0,255] - rgbData[index] = static_cast(color.r * 255); - rgbData[index + 1] = static_cast(color.g * 255); - rgbData[index + 2] = static_cast(color.b * 255); + // Convert float color [0,1] to int [0,255] in BGR format + rgbData[index + 2] = static_cast(color.b * 255); // Blue channel + rgbData[index + 1] = static_cast(color.g * 255); // Green channel + rgbData[index] = static_cast(color.r * 255); // Red channel } } } } } - - void getRegionAsRGB(const Vec2& minCorner, const Vec2& maxCorner, - int& width, int& height, std::vector& rgbData) const { - getRegionAsRGB(minCorner.x, minCorner.y, maxCorner.x, maxCorner.y, - width, height, rgbData); + + void getGridRegionAsRGB(float minX, float minY, float maxX, float maxY, + int& width, int& height, std::vector& rgbData) const { + getGridRegionAsRGB(Vec2(minX, minY), Vec2(maxX, maxY), width, height, rgbData); + } + + void getGridAsRGB(int& width, int& height, std::vector& rgbData) const { + TIME_FUNCTION; + + // Get the bounding box of all objects + Vec2 minCorner, maxCorner; + getBoundingBox(minCorner, maxCorner); + + // Use the main function to get BGR data for the entire region + getGridRegionAsRGB(minCorner, maxCorner, width, height, rgbData); + } + + void getGridRegionAsBGR(const Vec2& minCorner, const Vec2& maxCorner, + int& width, int& height, std::vector& bgrData) const { + TIME_FUNCTION; + + // Ensure valid region + if (minCorner.x >= maxCorner.x || minCorner.y >= maxCorner.y) { + width = 0; + height = 0; + bgrData.clear(); + return; + } + + // Calculate grid dimensions + width = static_cast(std::ceil(maxCorner.x - minCorner.x)); + height = static_cast(std::ceil(maxCorner.y - minCorner.y)); + + // Initialize with black (0,0,0) in BGR format + bgrData.resize(width * height * 3, 0); + + // Fill the grid with object colors in the region, accounting for sizes + for (const auto& posPair : positions) { + size_t id = posPair.first; + const Vec2& pos = posPair.second; + float size = getSize(id); + const Vec4& color = getColor(id); + + // Calculate the bounding box of this object in world coordinates + float halfSize = size * 0.5f; + float objMinX = pos.x - halfSize; + float objMinY = pos.y - halfSize; + float objMaxX = pos.x + halfSize; + float objMaxY = pos.y + halfSize; + + // Check if object overlaps with the region + if (objMaxX >= minCorner.x && objMinX <= maxCorner.x && + objMaxY >= minCorner.y && objMinY <= maxCorner.y) { + + // Calculate overlapping region in grid coordinates + int minGridX = static_cast(std::floor(std::max(objMinX, minCorner.x) - minCorner.x)); + int minGridY = static_cast(std::floor(std::max(objMinY, minCorner.y) - minCorner.y)); + int maxGridX = static_cast(std::ceil(std::min(objMaxX, maxCorner.x) - minCorner.x)); + int maxGridY = static_cast(std::ceil(std::min(objMaxY, maxCorner.y) - minCorner.y)); + + // Clamp to grid boundaries + minGridX = std::max(0, minGridX); + minGridY = std::max(0, minGridY); + maxGridX = std::min(width - 1, maxGridX); + maxGridY = std::min(height - 1, maxGridY); + + // Fill all pixels within the object's overlapping region in BGR format + for (int y = minGridY; y <= maxGridY; ++y) { + for (int x = minGridX; x <= maxGridX; ++x) { + int index = (y * width + x) * 3; + + // Convert float color [0,1] to int [0,255] in BGR format + bgrData[index] = static_cast(color.b * 255); // Blue channel + bgrData[index + 1] = static_cast(color.g * 255); // Green channel + bgrData[index + 2] = static_cast(color.r * 255); // Red channel + } + } + } + } + } + + // Helper function that takes individual coordinates instead of Vec2 + void getGridRegionAsBGR(float minX, float minY, float maxX, float maxY, + int& width, int& height, std::vector& bgrData) const { + getGridRegionAsBGR(Vec2(minX, minY), Vec2(maxX, maxY), width, height, bgrData); + } + + // Helper function that gets the entire grid bounds and returns as BGR + void getGridAsBGR(int& width, int& height, std::vector& bgrData) const { + TIME_FUNCTION; + + // Get the bounding box of all objects + Vec2 minCorner, maxCorner; + getBoundingBox(minCorner, maxCorner); + + // Use the main function to get BGR data for the entire region + getGridRegionAsBGR(minCorner, maxCorner, width, height, bgrData); } //spatial map diff --git a/util/output/aviwriter.hpp b/util/output/aviwriter.hpp index 72c2fae..6d1728d 100644 --- a/util/output/aviwriter.hpp +++ b/util/output/aviwriter.hpp @@ -118,8 +118,8 @@ public: return false; } - std::cout << "1" << "width: " << width << - "height: " << height << "frame count: " << fps << std::endl; + // std::cout << "1" << "width: " << width << + // "height: " << height << "frame count: " << fps << std::endl; // Validate frame sizes size_t expectedFrameSize = width * height * 3; @@ -129,13 +129,13 @@ public: } } - std::cout << "2" << std::endl; + // std::cout << "2" << std::endl; // Create directory if needed if (!createDirectoryIfNeeded(filename)) { return false; } - std::cout << "3" << std::endl; + // std::cout << "3" << std::endl; std::ofstream file(filename, std::ios::binary); if (!file) { return false; @@ -149,7 +149,7 @@ public: uint32_t frameSize = rowSize * height; uint32_t totalDataSize = frameCount * frameSize; - std::cout << "4" << std::endl; + // std::cout << "4" << std::endl; // RIFF AVI header RIFFChunk riffHeader; riffHeader.chunkId = 0x46464952; // 'RIFF' @@ -163,7 +163,7 @@ public: uint32_t hdrlListStart = static_cast(file.tellp()); writeList(file, 0x6C726468, nullptr, 0); // 'hdrl' - we'll fill size later - std::cout << "5" << std::endl; + // std::cout << "5" << std::endl; // avih chunk AVIMainHeader mainHeader; mainHeader.microSecPerFrame = microSecPerFrame; @@ -183,7 +183,7 @@ public: writeChunk(file, 0x68697661, &mainHeader, sizeof(mainHeader)); // 'avih' - std::cout << "6" << std::endl; + // std::cout << "6" << std::endl; // strl list uint32_t strlListStart = static_cast(file.tellp()); writeList(file, 0x6C727473, nullptr, 0); // 'strl' - we'll fill size later @@ -226,7 +226,7 @@ public: writeChunk(file, 0x66727473, &bitmapInfo, sizeof(bitmapInfo)); // 'strf' - std::cout << "7" << std::endl; + // std::cout << "7" << std::endl; // Update strl list size uint32_t strlListEnd = static_cast(file.tellp()); file.seekp(strlListStart + 4); @@ -234,7 +234,7 @@ public: file.write(reinterpret_cast(&strlListSize), 4); file.seekp(strlListEnd); - std::cout << "8" << std::endl; + // std::cout << "8" << std::endl; // Update hdrl list size uint32_t hdrlListEnd = static_cast(file.tellp()); file.seekp(hdrlListStart + 4); @@ -242,7 +242,7 @@ public: file.write(reinterpret_cast(&hdrlListSize), 4); file.seekp(hdrlListEnd); - std::cout << "9" << std::endl; + // std::cout << "9" << std::endl; // movi list uint32_t moviListStart = static_cast(file.tellp()); writeList(file, 0x69766F6D, nullptr, 0); // 'movi' - we'll fill size later @@ -254,7 +254,7 @@ public: for (uint32_t i = 0; i < frameCount; ++i) { uint32_t frameStart = static_cast(file.tellp()) - moviListStart - 4; - std::cout << "10-" << i << std::endl; + // std::cout << "10-" << i << std::endl; // Create padded frame data (BMP-style bottom-to-top with padding) std::vector paddedFrame(frameSize, 0); const auto& frame = frames[i]; @@ -268,7 +268,7 @@ public: // Padding bytes remain zeros } - std::cout << "11-" << i << std::endl; + // std::cout << "11-" << i << std::endl; // Write frame as '00db' chunk writeChunk(file, 0x62643030, paddedFrame.data(), frameSize); // '00db' @@ -281,7 +281,7 @@ public: indexEntries.push_back(entry); } - std::cout << "12" << std::endl; + // std::cout << "12" << std::endl; // Update movi list size uint32_t moviListEnd = static_cast(file.tellp()); file.seekp(moviListStart + 4); @@ -289,7 +289,7 @@ public: file.write(reinterpret_cast(&moviListSize), 4); file.seekp(moviListEnd); - std::cout << "13" << std::endl; + // std::cout << "13" << std::endl; // idx1 chunk - index uint32_t idx1Size = static_cast(indexEntries.size() * sizeof(AVIIndexEntry)); writeChunk(file, 0x31786469, indexEntries.data(), idx1Size); // 'idx1' @@ -300,7 +300,7 @@ public: uint32_t riffSize = fileEnd - riffStartPos - 8; file.write(reinterpret_cast(&riffSize), 4); - std::cout << "14" << std::endl; + // std::cout << "14" << std::endl; return true; }