aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan <boss@tehbox.org>2026-03-18 16:32:29 +1300
committerDylan <boss@tehbox.org>2026-03-18 16:32:29 +1300
commite2e9be992b948595086db6ac62cfb5b822c622d6 (patch)
tree83246401b9bbb4a6a9f302cf58f3ef6bd39b9c63
parent93a78ac64327b53f53952b625c7ce8a11bcc8651 (diff)
downloadtehimage-webp.tar.gz
tehimage-webp.zip
feat: Started on webp implementationwebp
Currently very basic, can only read simple things such as width and height
-rw-r--r--GNUmakefile1
-rw-r--r--src/WEBPImage.cpp102
-rw-r--r--src/WEBPImage.h38
-rw-r--r--test/main.cpp7
4 files changed, 145 insertions, 3 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 4f3b83b..08d374e 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -61,5 +61,6 @@ test: $(TEST)
$(OBJS_DIR)/reader.o: $(SOURCE_DIR)/debug.h
$(OBJS_DIR)/image.o:
$(OBJS_DIR)/PNGImage.o: $(SOURCE_DIR)/debug.h $(SOURCE_DIR)/image.h
+$(OBJS_DIR)/WEBPImage.o: $(SOURCE_DIR)/debug.h $(SOURCE_DIR)/image.h
$(OBJS_DIR)/BMPImage.o: $(SOURCE_DIR)/image.h
$(OBJS_DIR)/zlib.o:
diff --git a/src/WEBPImage.cpp b/src/WEBPImage.cpp
new file mode 100644
index 0000000..4c4652e
--- /dev/null
+++ b/src/WEBPImage.cpp
@@ -0,0 +1,102 @@
+#include "WEBPImage.h"
+#include "reader.h"
+
+#define ENABLE_DEBUG
+#include "debug.h"
+
+#include <iostream>
+
+using std::cout, std::endl;
+
+namespace TehImage
+{
+ int WEBPImage::writeToFile(std::string filename)
+ {
+ cout << "Not implemented" << endl;
+ return 1;
+ }
+
+ int WEBPImage::readFromFile(std::string filename)
+ {
+ static_assert(std::endian::native == std::endian::little, "Must use little endian");
+ reader = std::make_unique<Reader>(filename, FileEndianness::LITTLE);
+
+ refreshBitBuffer();
+
+ char RIFF[4], WEBP[4];
+ char RIFFExpected[] = {'R','I','F','F'};
+ readFourCC(RIFF);
+ uint32_t imgSize = readBits(32);
+ readFourCC(WEBP);
+ char WEBPExpected[] = {'W','E','B','P'};
+ if(strncmp(RIFF, RIFFExpected, 4) != 0 || strncmp(WEBP, WEBPExpected, 4) != 0)
+ {
+ cout << "Not a webp" << endl;
+ // cout << '#' << std::hex << RIFF.raw << " #" << RIFFExpected.raw << std::dec << endl;
+ // cout << '#' << std::hex << WEBP.raw << " #" << WEBPExpected.raw << std::dec << endl;
+ return 1;
+ }
+
+ // refreshBitBuffer();
+
+ char VP8L[4];
+ readFourCC(VP8L);
+ char VP8LExpected[] = {'V', 'P', '8', 'L'};
+ uint32_t VP8LSize = readBits(32);
+ uint8_t signature = readBits(8);
+ if(strncmp(VP8L, VP8LExpected, 4) != 0)
+ {
+ cout << "VP8L error" << endl;
+ return 1;
+ }
+
+ uint16_t width = readBits(14) + 1;
+ uint16_t height = readBits(14) + 1;
+
+ cout << width << " " << height << endl;
+
+ bool alpha = readBits(1);
+ uint8_t versionNumber = readBits(3);
+
+ cout << "Alpha: " << (alpha?"Y":"N") << ", version: " << 0+versionNumber << endl;
+
+ if (readBits(1)) {
+ cout << (int) readBits(2) << endl;
+ }
+
+ cout << "Not finished" << endl;
+ return 1;
+ }
+
+ bool WEBPImage::readBit()
+ {
+ bool res = bitBuffer & (1 << (bitBufferPos++));
+ if(bitBufferPos >= 8)
+ refreshBitBuffer();
+ return res?1:0;
+ }
+
+ uint32_t WEBPImage::readBits(size_t count)
+ {
+ uint32_t out = 0;
+ for(int i = 0; i < count; i++)
+ {
+ out |= readBit() << i;
+ }
+ return out;
+ }
+
+ void WEBPImage::readFourCC(char* dest)
+ {
+ for(int i = 0; i < 4; i++)
+ {
+ dest[i] = readBits(8);
+ }
+ }
+
+ void WEBPImage::refreshBitBuffer()
+ {
+ bitBuffer = reader->readByte();
+ bitBufferPos = 0;
+ }
+}
diff --git a/src/WEBPImage.h b/src/WEBPImage.h
new file mode 100644
index 0000000..8a87b08
--- /dev/null
+++ b/src/WEBPImage.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "image.h"
+#include "reader.h"
+
+#define BIT_BUFFER_SIZE 1024
+
+namespace TehImage
+{
+ typedef enum {
+ PREDICTOR_TRANSFORM = 0,
+ COLOR_TRANSFORM = 1,
+ SUBTRACT_GREEN_TRANSFORM = 2,
+ COLOR_INDEXING_TRANSFORM = 3,
+ } TransformType;
+
+ class WEBPImage : public Image
+ {
+ public:
+ WEBPImage() = default;
+ ~WEBPImage() = default;
+
+ WEBPImage(const Image& other) : Image(other) {}
+
+ int readFromFile(std::string filename) override;
+ int writeToFile(std::string filename) override;
+
+ private:
+ std::unique_ptr<Reader> reader;
+ uint8_t bitBuffer;
+ size_t bitBufferPos = 0;
+
+ bool readBit();
+ uint32_t readBits(size_t count);
+ void readFourCC(char* dest);
+ void refreshBitBuffer();
+ };
+}
diff --git a/test/main.cpp b/test/main.cpp
index d4c2e64..d1633b8 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -2,6 +2,7 @@
#include <debug.h>
#include <PNGImage.h>
#include <BMPImage.h>
+#include <WEBPImage.h>
#include <zlib.h>
#include <cstdint>
#include <cstring>
@@ -21,9 +22,9 @@ int main(int argc, char* argv[])
std::string outfile = argv[2];
- TehImage::PNGImage png;
- png.readFromFile(infile);
+ TehImage::WEBPImage webp;
+ webp.readFromFile(infile);
- TehImage::BMPImage bmp(png);
+ TehImage::BMPImage bmp(webp);
bmp.writeToFile(outfile);
}