-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloadJpeg.cpp
More file actions
112 lines (97 loc) · 3.69 KB
/
loadJpeg.cpp
File metadata and controls
112 lines (97 loc) · 3.69 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <ImageIO/loadImage.h>
#include <ImageIO/BitmapImpl.h>
#include <ImageIO/readBinaryFile.h>
#include <turbojpeg.h>
#include <fstream>
#include <stdexcept>
namespace ImageIO_NS
{
namespace
{
using ::imageview::PixelFormatGrayscale8;
using ::imageview::PixelFormatRGB24;
class TjDecompressor
{
public:
TjDecompressor():
handle_(tjInitDecompress())
{}
TjDecompressor(const TjDecompressor&) = delete;
TjDecompressor(TjDecompressor&& other) noexcept:
handle_(std::exchange(other.handle_, nullptr))
{}
TjDecompressor& operator=(const TjDecompressor&) = delete;
TjDecompressor& operator=(TjDecompressor&& other)
{
tjDestroy(handle_);
handle_ = std::exchange(other.handle_, nullptr);
}
~TjDecompressor()
{
if (handle_) {
tjDestroy(handle_);
}
}
constexpr tjhandle get() const { return handle_; }
private:
tjhandle handle_ = nullptr;
};
std::unique_ptr<IBitmap<PixelFormatGrayscale8>>
loadJpegFromMemoryGrayscale8(std::span<const std::byte> compressed_data)
{
TjDecompressor jpeg_decompressor;
int width = 0;
int height = 0;
int jpeg_subsamp = 0;
int jpeg_colorspace = 0;
tjDecompressHeader3(
jpeg_decompressor.get(),
reinterpret_cast<const unsigned char*>(compressed_data.data()),
static_cast<unsigned long>(compressed_data.size()), &width, &height,
&jpeg_subsamp, &jpeg_colorspace);
std::vector<unsigned char> buffer(width * height *
PixelFormatRGB24::kBytesPerPixel);
tjDecompress2(jpeg_decompressor.get(),
reinterpret_cast<const unsigned char*>(compressed_data.data()),
static_cast<unsigned long>(compressed_data.size()),
buffer.data(), width, 0 /*pitch*/, height, TJPF_GRAY,
TJFLAG_FASTDCT);
return std::make_unique<BitmapImpl<PixelFormatGrayscale8>>(
static_cast<unsigned int>(height), static_cast<unsigned int>(width),
std::move(buffer));
}
std::unique_ptr<IBitmap<PixelFormatRGB24>> loadJpegFromMemoryRGB24(std::span<const std::byte> compressed_data)
{
TjDecompressor jpeg_decompressor;
int width = 0;
int height = 0;
int jpeg_subsamp = 0;
int jpeg_colorspace = 0;
tjDecompressHeader3(
jpeg_decompressor.get(),
reinterpret_cast<const unsigned char*>(compressed_data.data()),
static_cast<unsigned long>(compressed_data.size()), &width, &height,
&jpeg_subsamp, &jpeg_colorspace);
std::vector<unsigned char> buffer(width * height *
PixelFormatRGB24::kBytesPerPixel);
tjDecompress2(jpeg_decompressor.get(),
reinterpret_cast<const unsigned char*>(compressed_data.data()),
static_cast<unsigned long>(compressed_data.size()),
buffer.data(), width, 0 /*pitch*/, height, TJPF_RGB,
TJFLAG_FASTDCT);
return std::make_unique<BitmapImpl<PixelFormatRGB24>>(
static_cast<unsigned int>(height), static_cast<unsigned int>(width),
std::move(buffer));
}
}
std::unique_ptr<IBitmap<PixelFormatGrayscale8>> loadJpegGrayscale8(const std::filesystem::path& path)
{
const Blob compressed_data = readBinaryFile(path);
return loadJpegFromMemoryGrayscale8(compressed_data.data());
}
std::unique_ptr<IBitmap<PixelFormatRGB24>> loadJpegRGB24(const std::filesystem::path& path)
{
const Blob compressed_data = readBinaryFile(path);
return loadJpegFromMemoryRGB24(compressed_data.data());
}
}