diff options
| author | Dylan <boss@tehbox.org> | 2026-03-18 16:32:29 +1300 |
|---|---|---|
| committer | Dylan <boss@tehbox.org> | 2026-03-18 16:32:29 +1300 |
| commit | e2e9be992b948595086db6ac62cfb5b822c622d6 (patch) | |
| tree | 83246401b9bbb4a6a9f302cf58f3ef6bd39b9c63 | |
| parent | 93a78ac64327b53f53952b625c7ce8a11bcc8651 (diff) | |
| download | tehimage-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-- | GNUmakefile | 1 | ||||
| -rw-r--r-- | src/WEBPImage.cpp | 102 | ||||
| -rw-r--r-- | src/WEBPImage.h | 38 | ||||
| -rw-r--r-- | test/main.cpp | 7 |
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); } |
