commit 524192288a32ee69b28143d1d7e67eb09b4b2609
parent b3ac8d603e00e9bd9b3d0d5996895d977483b60f
Author: Andrew Laack <andrew@laack.co>
Date: Thu, 10 Jul 2025 17:28:35 -0500
Finished setting up encoder and decoder portions, verified they always match. Next I need to figure out how to stitch these together into a video and then finally improve performance.
Diffstat:
4 files changed, 178 insertions(+), 7 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,3 @@
*.out
+*.txt
+*.tga
diff --git a/src/chunk.cpp b/src/chunk.cpp
@@ -1,6 +1,98 @@
# include "chunk.h"
# include <iostream>
# include <fstream>
+# include <bitset>
+# include <sstream>
+
+
+// read in saved chunk from file
+Chunk::Chunk(std::string filename){
+
+ std::ifstream file;
+
+ file.open(filename);
+
+ std::string fileString = "";
+
+ char byte;
+
+ while (file.read(&byte, 1)) {
+ fileString += byte;
+ }
+
+ file.close();
+
+ // header, comment, dims
+
+
+ std::string header = "";
+ std::string comment = "";
+ std::string dims = "";
+
+ int itr = 0;
+ while (fileString[itr] != '\n'){
+ header += fileString[itr];
+ itr += 1;
+ }
+
+ itr += 1;
+
+ while (fileString[itr] != '\n'){
+ comment += fileString[itr];
+ 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;
+
+ while (fileString[itr] != '\n'){
+ dims += fileString[itr];
+ itr += 1;
+ }
+
+ itr += 1;
+
+
+ std::string content = "";
+
+ while(itr < fileString.size()){
+ if (fileString[itr] != ' ' && fileString[itr] != '\n'){
+ content += fileString[itr];
+ }
+ itr += 1;
+ }
+
+
+ std::vector<char> bytes;
+
+
+ for (int i = 0 ; i < characters; ++i){
+
+ std::string current = "";
+
+ for (int itr = 0; itr < 8; ++itr){
+ current += content[i * 8 + itr];
+ }
+
+ std::bitset<8> bits(current);
+
+ char recovered_char = static_cast<char>(bits.to_ulong());
+
+ bytes.push_back(recovered_char);
+ }
+
+ this->chunk = bytes;
+}
Chunk::Chunk(std::vector<char> chunkData){
this->chunk = chunkData;
@@ -43,6 +135,76 @@ void Chunk::writeChunk(std::string filename){
}
}
+
+void Chunk::writeVideo(std::string filename){
+ std::cout << "NOT IMPLEMENTED" << std::endl;
+}
+
+void Chunk::writeImage(std::string filename, uint chunkNumber, std::string originalFilename, uint x, uint y){
+
+ Chunk chunk = this->chunk;
+
+ std::vector<char> data = chunk.getChunk();
+
+
+ if (x * y < data.size() * 8){
+ throw std::invalid_argument("x and y dimensions are too small for the chunk.");
+ }
+
+ std::string header = "P1\n";
+ std::string comment = "# ";
+ comment.append(originalFilename);
+ // we assume no spaces in original filename
+ comment.append(" ");
+ comment.append(std::to_string(chunkNumber));
+ comment += " ";
+ comment += std::to_string(data.size());
+ comment.append("\n");
+
+ std::string dims = std::to_string(x);
+ dims += " ";
+ dims += std::to_string(y);
+ dims += ("\n");
+
+
+ std::string image = header + comment + dims;
+
+
+ int target = x * y;
+ int added = 0;
+
+ uint xPos = 0;
+ for (char chr : data){
+ std::string current = std::bitset<8>(chr).to_string();
+ for (int i = 0 ; i < 8; ++i){
+ if (xPos == x){
+ image.append("\n");
+ xPos = 0;
+ }
+ image += current[i];
+ added += 1;
+ image.append(" ");
+
+ xPos += 1;
+ }
+ }
+
+ while (added < target){
+ if (xPos == x){
+ image += "\n";
+ xPos = 0;
+ }
+ image += "0 ";
+ added += 1;
+ xPos += 1;
+ }
+
+ std::ofstream file = std::ofstream(filename);
+
+ file << image;
+
+}
+
void Chunk::print(){
for(int i = 0 ; i < this->chunk.size(); ++i){
std::cout << chunk[i];
diff --git a/src/chunk.h b/src/chunk.h
@@ -6,11 +6,14 @@ 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
@@ -11,15 +11,19 @@ int main(int argc, char* argv[]){
std::string source = argv[1];
std::string destination = argv[2];
-
- Chunk chunk = Chunk(source, 0, 1000000);
- chunk.print();
+ Chunk chunk = Chunk(source, 0, 100000000);
std::vector<char> bytes = chunk.getChunk();
-
std::ofstream outFile;
-
Chunk outChunk = Chunk(bytes);
- outChunk.writeChunk(destination);
+ 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;
return 0;
}