unlimited-storage

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit b63a1e993c7d3f6346b69cc8f709835e1035c1e5
parent a0715f6de63b1242af01eb5640248bc06496475f
Author: Andrew Laack <andrew@laack.co>
Date:   Fri, 11 Jul 2025 12:28:44 -0500

Refactored project structure, updated reading header info from image, verified both sides work as expected.

Diffstat:
AMakefile | 8++++++++
Ainclude/chunk.h | 38++++++++++++++++++++++++++++++++++++++
Ainclude/debug.h | 5+++++
Msrc/chunk.cpp | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Dsrc/chunk.h | 19-------------------
Msrc/encode.cpp | 23+++++++++++++++--------
6 files changed, 166 insertions(+), 56 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,8 @@ +debug: + g++ -Wall -oO src/chunk.cpp src/encode.cpp -o build/debug.out -DDEBUG + +release: + g++ -Wall -O2 src/chunk.cpp src/encode.cpp -o build/release.out -DRELEASE + +clean: + rm -rf build/* diff --git a/include/chunk.h b/include/chunk.h @@ -0,0 +1,38 @@ +#include <iostream> +#include <memory> +#include <vector> + + +// HEADER (this data is encoded in the image itself): +// chunk number 4 bytes +// characters 4 bytes +// fnamelen 4 bytes +// filename fnamelen + +struct Header { + uint chunkNumber; + uint characters; + uint fnameLength; + std::string filename; +}; + +class Chunk{ + +private: + std::vector<char> chunk; + std::string extractEncodedSection(const std::string& fileString, uint& itr, int count); + std::string binaryToAscii(const std::string& binaryStr); + +public: + Chunk(std::string filename, uint start, uint size); + Chunk(std::vector<char> chunkData); + // read in the written chunk from tga format. + Chunk(std::string filename); + std::vector<char> getChunk(); + void writeChunk(std::string filename); + void writeVideo(std::string filename); + void writeImage(std::string filename, uint chunkNumber, std::string originalFilename, uint x, uint y); + void print(); + std::string toString(); +}; + diff --git a/include/debug.h b/include/debug.h @@ -0,0 +1,5 @@ +#ifdef DEBUG + #define LOG(x) std::cout << x << std::endl; +#else + #define LOG(x) +#endif diff --git a/src/chunk.cpp b/src/chunk.cpp @@ -1,8 +1,8 @@ -# include "chunk.h" +# include "../include/chunk.h" # include <iostream> # include <fstream> # include <bitset> -# include <sstream> +# include "../include/debug.h" // read in saved chunk from file @@ -22,14 +22,13 @@ Chunk::Chunk(std::string filename){ file.close(); - // header, comment, dims + // header (.tga header), comment (.tga comment), dims (.tga spec) - std::string header = ""; std::string comment = ""; std::string dims = ""; - int itr = 0; + uint itr = 0; while (fileString[itr] != '\n'){ header += fileString[itr]; itr += 1; @@ -42,16 +41,6 @@ Chunk::Chunk(std::string filename){ itr += 1; } - std::stringstream ss(comment); - std::string token; - std::vector<std::string> parts; - - while (ss >> token) { - parts.push_back(token); - } - - std::string last_part = parts.back(); - int characters = std::stoi(last_part); itr += 1; @@ -65,6 +54,45 @@ Chunk::Chunk(std::string filename){ std::string content = ""; + // ENCODED HEADER (this data is encoded in the image itself): + // chunk number 4 bytes + // characters 4 bytes + // fnamelen 4 bytes + // filename fnamelen + + + + Header head; + + head.chunkNumber = 0; + head.characters = 0; + head.fnameLength = 0; + head.filename = ""; + + std::string encodedCNum = extractEncodedSection(fileString, itr, 4 * 8); + std::string encodedCharacters = extractEncodedSection(fileString, itr, 4 * 8); + std::string encodedFnameLength = extractEncodedSection(fileString, itr, 4 * 8); + + head.characters = std::bitset<4*8>(encodedCharacters).to_ullong(); + head.chunkNumber = std::bitset<4*8>(encodedCNum).to_ullong(); + head.fnameLength = std::bitset<4*8>(encodedFnameLength).to_ullong(); + + std::string encodedFname = extractEncodedSection(fileString, itr, head.fnameLength); + head.filename = binaryToAscii(encodedFname); + + LOG("ENCODED CNUM: " << encodedCNum) + LOG("CNUM: " << head.chunkNumber) + + LOG("ENCODED CHARACTERS: " << encodedCharacters) + LOG("CHARACTERS: " << head.characters) + + LOG("ENCODED FNAMELENGTH: " << encodedFnameLength) + LOG("FNAMELENGTH: " << head.fnameLength) + + + LOG("ENCODED FNAME: " << encodedFname) + LOG("FNAME: " << head.filename) + while(itr < fileString.size()){ if (fileString[itr] != ' ' && fileString[itr] != '\n'){ content += fileString[itr]; @@ -72,11 +100,10 @@ Chunk::Chunk(std::string filename){ itr += 1; } - std::vector<char> bytes; - for (int i = 0 ; i < characters; ++i){ + for (int i = 0 ; i < head.characters; ++i){ std::string current = ""; @@ -130,7 +157,7 @@ void Chunk::writeChunk(std::string filename){ outFile.open(filename, std::ios::binary | std::ios::out); - for(int i = 0 ; i < bytes.size(); ++i){ + for(uint i = 0 ; i < bytes.size(); ++i){ outFile.write(&bytes[i], 1); } } @@ -140,8 +167,6 @@ void Chunk::writeVideo(std::string filename){ std::cout << "NOT IMPLEMENTED" << std::endl; } - - // HEADER: // - chunk number 4 bytes // - characters 4 bytes @@ -161,7 +186,8 @@ void Chunk::writeImage(std::string filename, uint chunkNumber, std::string origi std::string chunkNumberEncoded = std::bitset<8*4>(chunkNumber).to_string(); std::string charactersEncoded = std::bitset<8*4>(data.size()).to_string(); - std::cout << data.size() << std::endl; + + LOG(data.size()) std::string dims = std::to_string(x); @@ -176,7 +202,7 @@ void Chunk::writeImage(std::string filename, uint chunkNumber, std::string origi filenameEncoded += std::bitset<8>(filename.c_str()[i]).to_string(); } - std::cout << filenameEncoded << std::endl; + LOG(filenameEncoded) dims += " "; dims += std::to_string(y); @@ -190,14 +216,16 @@ void Chunk::writeImage(std::string filename, uint chunkNumber, std::string origi std::string header = chunkNumberEncoded + charactersEncoded + filenameLengthEncoded + filenameEncoded; - std::cout << chunkNumberEncoded.size() << " - " << chunkNumberEncoded << std::endl; - std::cout << charactersEncoded.size() << " - " << charactersEncoded << std::endl; - std::cout << filenameLengthEncoded.size() << " - " << filenameLengthEncoded << std::endl; - std::cout << filenameEncoded.size() << " - " << filenameEncoded << std::endl; - std::cout << "HEADER: " << header << std::endl; + LOG(chunkNumberEncoded.size() + " - " + chunkNumberEncoded) + LOG(charactersEncoded.size() + " - " + charactersEncoded) + LOG(filenameLengthEncoded.size() + " - " + filenameLengthEncoded) + LOG(filenameEncoded.size() + " - " + filenameEncoded) + + LOG("HEADER: " + header) if (x * y < (data.size() * 8) + header.size()){ + LOG(data.size() * 8 + header.size()) throw std::invalid_argument("x and y dimensions are too small for the chunk."); } @@ -213,7 +241,7 @@ void Chunk::writeImage(std::string filename, uint chunkNumber, std::string origi xPos += 1; } - std::cout << image << std::endl; + LOG(image) int target = x * y; int added = 0; @@ -246,11 +274,54 @@ void Chunk::writeImage(std::string filename, uint chunkNumber, std::string origi std::ofstream file = std::ofstream(filename); file << image; +} + +std::string Chunk::toString(){ + + std::string str = ""; + + for(uint i = 0 ; i < this->chunk.size(); ++i){ + str += chunk[i]; + } + return str; } void Chunk::print(){ - for(int i = 0 ; i < this->chunk.size(); ++i){ + for(uint i = 0 ; i < this->chunk.size(); ++i){ std::cout << chunk[i]; } } + +std::string Chunk::extractEncodedSection(const std::string& fileString, uint& itr, int count) { + std::string result; + int collected = 0; + + while (collected < count && itr < fileString.size()) { + char ch = fileString[itr]; + + if (!std::isspace(static_cast<unsigned char>(ch))) { + result += ch; + collected += 1; + } + itr += 1; + } + + return result; +} + +std::string Chunk::binaryToAscii(const std::string& binaryStr) { + std::string asciiStr; + + if (binaryStr.size() % 8 != 0) { + throw std::invalid_argument("Length must be multiple of 8"); + } + + for (size_t i = 0; i < binaryStr.size(); i += 8) { + std::string byteString = binaryStr.substr(i, 8); + char c = static_cast<char>(std::stoi(byteString, nullptr, 2)); + asciiStr += c; + } + + return asciiStr; +} diff --git a/src/chunk.h b/src/chunk.h @@ -1,19 +0,0 @@ -#include <iostream> -#include <memory> -#include <vector> - -class Chunk{ - -private: - std::vector<char> chunk; -public: - Chunk(std::string filename, uint start, uint size); - Chunk(std::vector<char> chunkData); - // read in the written chunk from tga format. - Chunk(std::string filename); - std::vector<char> getChunk(); - void writeChunk(std::string filename); - void writeVideo(std::string filename); - void writeImage(std::string filename, uint chunkNumber, std::string originalFilename, uint x, uint y); - void print(); -}; diff --git a/src/encode.cpp b/src/encode.cpp @@ -1,6 +1,9 @@ #include <vector> #include <fstream> -#include "chunk.h" +#include "../include/chunk.h" +#include "iostream" +#include "../include/debug.h" + int main(int argc, char* argv[]){ @@ -11,19 +14,23 @@ int main(int argc, char* argv[]){ std::string source = argv[1]; std::string destination = argv[2]; - Chunk chunk = Chunk(source, 0, 100000000); + Chunk chunk = Chunk(source, 0, 1000000000); std::vector<char> bytes = chunk.getChunk(); std::ofstream outFile; Chunk outChunk = Chunk(bytes); outChunk.writeImage(destination, 1, source, 1920, 1080); - std::cout << "BEFORE: " << std::endl; - // outChunk.print(); - std::cout << std::endl; Chunk readChunk = Chunk(destination); - std::cout << "AFTER: " << std::endl; - // readChunk.print(); - std::cout << std::endl; + + std::string beforeChunk = readChunk.toString(); + std::string afterChunk = outChunk.toString(); + + if (beforeChunk == afterChunk){ + LOG("CHUNKS MATCH") + } + else{ + LOG("CHUNKS DON'T MATCH") + } return 0; }