-
Notifications
You must be signed in to change notification settings - Fork 3
/
io_webp.cpp
83 lines (62 loc) · 2.42 KB
/
io_webp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
* SPDX-FileCopyrightText: Copyright 2023 Julian Amann <dev@vertexwahn.de>
* SPDX-License-Identifier: CC-BY-SA-3.0
*/
#include "io_webp.h"
#include "webp/encode.h"
#include "webp/decode.h"
#include <fstream>
DE_VERTEXWAHN_BEGIN_NAMESPACE
bool store_webp(const char *filename, const Image4b &image) {
int stride = image.width() * static_cast<int>(sizeof(Color4b)); // TODO: stride should be moved to image class
uint8_t* out = nullptr;
auto encoded_size = WebPEncodeLosslessRGBA(image.data(), image.width(), image.height(), stride, &out);
// see https://stackoverflow.com/questions/11563963/how-to-write-a-large-buffer-into-a-binary-file-in-c-fast
FILE* file = fopen(filename, "wb");
fwrite(out, 1, encoded_size, file);
fclose(file);
return true;
}
// Copied from https://stackoverflow.com/questions/15138353/how-to-read-a-binary-file-into-a-vector-of-unsigned-chars
// Posted by jww
// Under CC-BY-SA-3.0 license
// License text can be found here https://creativecommons.org/licenses/by-sa/3.0/
// Modifications: Changed function name to lower snake case and replaced BYTE by uint8_t
// for this file the same license applies
std::vector<uint8_t> read_file(const char* filename)
{
// open the file:
std::ifstream file(filename, std::ios::binary);
// Stop eating new lines in binary mode!!!
file.unsetf(std::ios::skipws);
// get its size:
std::streampos fileSize;
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// reserve capacity
std::vector<uint8_t> vec;
vec.reserve(fileSize);
// read the data:
vec.insert(vec.begin(),
std::istream_iterator<uint8_t>(file),
std::istream_iterator<uint8_t>());
return vec;
}
ReferenceCounted<Image4b> load_image_webp(std::string_view filename) {
std::vector<uint8_t> encoded_webp = read_file(filename.data());
int width = 0;
int height = 0;
//WebPGetInfo(encoded_webp.data(), encoded_webp.size(), &width, &height);
uint8_t* decoded_data = WebPDecodeRGBA(encoded_webp.data(), encoded_webp.size(), &width, &height);
if(decoded_data == nullptr) {
std::runtime_error("Decoding WebP did not work.");
}
assert(decoded_data);
assert(width > 0);
assert(height > 0);
auto image = make_reference_counted<Image4b>(width, height, decoded_data);
WebPFree(decoded_data);
return image;
}
DE_VERTEXWAHN_END_NAMESPACE