summaryrefslogtreecommitdiff
path: root/src/vk/qoi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vk/qoi.cpp')
-rw-r--r--src/vk/qoi.cpp85
1 files changed, 22 insertions, 63 deletions
diff --git a/src/vk/qoi.cpp b/src/vk/qoi.cpp
index 8b7ef9e..4e2b2a4 100644
--- a/src/vk/qoi.cpp
+++ b/src/vk/qoi.cpp
@@ -19,6 +19,8 @@
#include <array>
#include <fstream>
+#include "../binary_reader.hpp"
+
namespace
{
@@ -88,26 +90,6 @@ color_hash(const RGBA &colors)
return colors.red*3 + colors.green*5 + colors.blue*7 + colors.alpha*11;
}
-void
-read_chars(uint8_t *data, int &p, char *str, int size)
-{
- for(int i{0}; i < size; i++) str[i] = (char)data[p++];
-}
-
-void
-read_ui8(uint8_t *data, int &p, uint8_t &num)
-{
- num = data[p++];
-}
-
-void
-read_ui32(uint8_t *data, int &p, uint32_t &num)
-{
- uint8_t b1{data[p++]}, b2{data[p++]}, b3{data[p++]}, b4{data[p++]};
-
- num = b1 << 24 | b2 << 16 | b3 << 8 | b4;
-}
-
}
namespace VK::QOI
@@ -116,38 +98,22 @@ namespace VK::QOI
Image::Image(const char *file_path, uint8_t channels):
channels{channels}
{
- int data_p{0};
- int data_size;
- uint8_t *data;
-
if(this->channels != 0 && this->channels != 3 && this->channels != 4)
{
throw std::invalid_argument{"invalid number of channels"};
}
- { // Read data from file.
- std::ifstream file(file_path, std::ios::binary | std::ios::ate);
- if(!file)
- {
- throw std::runtime_error{"failed to open QOI file"};
- }
-
- data_size = file.tellg();
- if(data_size < HEADER_SIZE + (int)sizeof(PADDING))
- {
- throw std::runtime_error{"invalid QOI file"};
- }
-
- file.seekg(0);
- data = new uint8_t[data_size];
- file.read((char*)data, data_size);
+ BinaryReader input{file_path};
+ if(input.size() < HEADER_SIZE + (int)sizeof(PADDING))
+ {
+ throw std::runtime_error{"invalid QOI file"};
}
- read_chars(data, data_p, this->header.magic, 4);
- read_ui32(data, data_p, this->header.width);
- read_ui32(data, data_p, this->header.height);
- read_ui8(data, data_p, this->header.channels);
- read_ui8(data, data_p, this->header.colorspace);
+ input.read_chars(this->header.magic, 4);
+ this->header.width = input.read_ui32();
+ this->header.height = input.read_ui32();
+ this->header.channels = input.read_ui8();
+ this->header.colorspace = input.read_ui8();
if(this->header.width == 0 || this->header.height == 0 ||
this->header.channels < 3 || this->header.channels > 4 ||
@@ -165,7 +131,7 @@ Image::Image(const char *file_path, uint8_t channels):
std::array<Pixel, 64> index;
Pixel pixel{};
- int chunks_len = data_size - (int)sizeof(PADDING);
+ int chunks_len = input.size() - (int)sizeof(PADDING);
/*
This algorithm is based on the original implementation that is in GitHub:
@@ -181,25 +147,22 @@ Image::Image(const char *file_path, uint8_t channels):
{
run--;
}
- else if(data_p < chunks_len)
+ else if(input.pointer() < chunks_len)
{
- uint8_t output;
- int b1;
- read_ui8(data, data_p, output);
- b1 = output;
+ int b1 = input.read_ui8();
if (b1 == OP_RGB)
{
- read_ui8(data, data_p, pixel.colors.red);
- read_ui8(data, data_p, pixel.colors.green);
- read_ui8(data, data_p, pixel.colors.blue);
+ pixel.colors.red = input.read_ui8();
+ pixel.colors.green = input.read_ui8();
+ pixel.colors.blue = input.read_ui8();
}
else if (b1 == OP_RGBA)
{
- read_ui8(data, data_p, pixel.colors.red);
- read_ui8(data, data_p, pixel.colors.green);
- read_ui8(data, data_p, pixel.colors.blue);
- read_ui8(data, data_p, pixel.colors.alpha);
+ pixel.colors.red = input.read_ui8();
+ pixel.colors.green = input.read_ui8();
+ pixel.colors.blue = input.read_ui8();
+ pixel.colors.alpha = input.read_ui8();
}
else if ((b1 & MASK_2_BITS) == OP_INDEX)
{
@@ -213,9 +176,7 @@ Image::Image(const char *file_path, uint8_t channels):
}
else if ((b1 & MASK_2_BITS) == OP_LUMA)
{
- int b2;
- read_ui8(data, data_p, output);
- b2 = output;
+ int b2 = input.read_ui8();
int vg = (b1 & 0x3f) - 32;
pixel.colors.red += vg - 8 + ((b2 >> 4) & 0x0f);
pixel.colors.green += vg;
@@ -234,8 +195,6 @@ Image::Image(const char *file_path, uint8_t channels):
this->pixels[pixel_p++] = pixel.colors.blue;
if(this->channels == 4) this->pixels[pixel_p++] = pixel.colors.alpha;
}
-
- delete[] data;
}
Image::~Image()