Skip to content

Commit

Permalink
更新 lithium.image 模块,重构图像加载和保存功能,新增 imgio.hpp 和 imgio.cpp 文件,优化 base64…
Browse files Browse the repository at this point in the history
… 编码解码函数,删除未使用的函数声明,改进 Platesolve2Solver 和 Platesolve3Solver 类的实现
  • Loading branch information
AstroAir committed Nov 16, 2024
1 parent 536bf24 commit 529fc4b
Show file tree
Hide file tree
Showing 33 changed files with 2,968 additions and 791 deletions.
8 changes: 5 additions & 3 deletions modules/lithium.image/include/base64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

#include <string>

std::string base64_encode(unsigned char const* bytes_to_encode,
unsigned int in_len);
std::string base64_decode(std::string const& encoded_string);
auto base64Encode(unsigned char const* bytes_to_encode,
unsigned int input_length) -> std::string;

auto base64Decode(std::string const& encoded_string) -> std::string;

#endif
34 changes: 34 additions & 0 deletions modules/lithium.image/include/bmp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef BMP_H
#define BMP_H

#include <array>
#include <cstdint>
#include <fstream>
#include <string>
#include <vector>

union ByteUnion {
uint32_t value;
std::array<std::byte, 4> bytes;
};

uint32_t littleToNative(uint32_t little);
uint16_t littleToNative(uint16_t little);

struct alignas(64) Image {
std::vector<std::byte> data;
std::vector<std::byte> greyData;
uint32_t sizeX, sizeY;

Image();
};

uint32_t readEndianInt(std::ifstream& file);
uint16_t readEndianShort(std::ifstream& file);

bool loadBMPImage(const std::string& filename, Image& image);
bool saveGrayImage(const std::string& filename, const Image& image);

int main(int argc, char* argv[]);

#endif // BMP_H
21 changes: 21 additions & 0 deletions modules/lithium.image/include/imgio.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef LITHIUM_MODULE_IMAGE_IMGIO_HPP
#define LITHIUM_MODULE_IMAGE_IMGIO_HPP

#include <string>
#include <vector>

namespace cv {
class Mat;
}
// 加载单张图像
auto loadImage(const std::string& filename, int flags = 1) -> cv::Mat;

// 从文件夹中读取所有图像
auto loadImages(const std::string& folder,
const std::vector<std::string>& filenames = {},
int flags = 1) -> std::vector<std::pair<std::string, cv::Mat>>;

// 保存图像到文件
auto saveImage(const std::string& filename, const cv::Mat& image) -> bool;

#endif
2 changes: 0 additions & 2 deletions modules/lithium.image/include/imgutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <tuple>
#include <vector>

std::vector<cv::Mat> loadImages(const std::string& folder,
const std::vector<std::string>& filenames);
bool insideCircle(int x, int y, int centerX, int centerY, float radius);
bool checkElongated(int width, int height);
int checkWhitePixel(const cv::Mat& rect_contour, int x, int y);
Expand Down
27 changes: 20 additions & 7 deletions modules/lithium.image/include/thumbhash.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
#ifndef THUMBHASH_H
#define THUMBHASH_H

#include <opencv2/opencv.hpp>
#include <string>
#include <vector>

#include "atom/macro.hpp"

struct YCbCr {
double y;
double cb;
double cr;
} ATOM_ALIGNAS(32);

namespace cv {
template <typename _Tp, int cn>
class Vec;
class Mat;
} // namespace cv

/**
* @brief Performs Discrete Cosine Transform (DCT) on the input image.
*
Expand All @@ -14,7 +27,7 @@
* @param input The input image matrix.
* @param output The output matrix to store the DCT result.
*/
void DCT(const cv::Mat& input, cv::Mat& output);
void dct(const cv::Mat& input, cv::Mat& output);

/**
* @brief Converts an RGB color to YCbCr color space.
Expand All @@ -27,7 +40,7 @@ void DCT(const cv::Mat& input, cv::Mat& output);
* @param Cb The output blue-difference chroma component.
* @param Cr The output red-difference chroma component.
*/
void RGBToYCbCr(const cv::Vec3b& rgb, double& Y, double& Cb, double& Cr);
auto rgbToYCbCr(const cv::Vec<unsigned char, 3>& rgb) -> YCbCr;

/**
* @brief Encodes an image into a ThumbHash.
Expand All @@ -38,7 +51,7 @@ void RGBToYCbCr(const cv::Vec3b& rgb, double& Y, double& Cb, double& Cr);
* @param image The input image to be encoded.
* @return A vector of doubles representing the encoded ThumbHash.
*/
std::vector<double> encodeThumbHash(const cv::Mat& image);
auto encodeThumbHash(const cv::Mat& image) -> std::vector<double>;

/**
* @brief Decodes a ThumbHash into an image.
Expand All @@ -50,8 +63,8 @@ std::vector<double> encodeThumbHash(const cv::Mat& image);
* @param height The height of the output thumbnail image.
* @return The decoded thumbnail image.
*/
cv::Mat decodeThumbHash(const std::vector<double>& thumbHash, int width,
int height);
auto decodeThumbHash(const std::vector<double>& thumbHash, int width,
int height) -> cv::Mat;

/**
* @brief Encodes ThumbHash data into a Base64 string.
Expand All @@ -62,6 +75,6 @@ cv::Mat decodeThumbHash(const std::vector<double>& thumbHash, int width,
* @param thumbHash The ThumbHash data to be encoded.
* @return A Base64 encoded string representing the ThumbHash data.
*/
std::string base64Encode(const std::vector<double>& thumbHash);
auto base64Encode(const std::vector<double>& thumbHash) -> std::string;

#endif // THUMBHASH_H
168 changes: 100 additions & 68 deletions modules/lithium.image/src/base64.cpp
Original file line number Diff line number Diff line change
@@ -1,93 +1,125 @@
#include "base64.hpp"

static const std::string base64_chars =
#include <array>
#include <string>

constexpr std::string_view BASE64_CHARS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

std::string base64_encode(unsigned char const* bytes_to_encode,
unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];

while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
constexpr unsigned char MASK_0X_FC = 0xFC;
constexpr unsigned char MASK_0X03 = 0x03;
constexpr unsigned char MASK_0X_F0 = 0xF0;
constexpr unsigned char MASK_0X0_F = 0x0F;
constexpr unsigned char MASK_0X_C0 = 0xC0;
constexpr unsigned char MASK_0X3_F = 0x3F;
constexpr unsigned char MASK_0X30 = 0x30;
constexpr unsigned char MASK_0X3_C = 0x3C;
constexpr int SHIFT_6 = 6;
constexpr int SHIFT_4 = 4;
constexpr int SHIFT_2 = 2;

auto base64Encode(unsigned char const* bytes_to_encode,
unsigned int input_length) -> std::string {
std::string result;
int index3 = 0;
std::array<unsigned char, 3> charArray3;
std::array<unsigned char, 4> charArray4;

while ((input_length--) != 0U) {
charArray3[index3++] = *(bytes_to_encode++);
if (index3 == 3) {
charArray4[0] = (charArray3[0] & MASK_0X_FC) >> SHIFT_2;
charArray4[1] = ((charArray3[0] & MASK_0X03) << SHIFT_4) +
((charArray3[1] & MASK_0X_F0) >> SHIFT_4);
charArray4[2] = ((charArray3[1] & MASK_0X0_F) << SHIFT_2) +
((charArray3[2] & MASK_0X_C0) >> SHIFT_6);
charArray4[3] = charArray3[2] & MASK_0X3_F;

for (index3 = 0; index3 < 4; index3++) {
result += BASE64_CHARS[charArray4[index3]];
}
index3 = 0;
}
}

if (i) {
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
if (index3 != 0) {
for (int j = index3; j < 3; j++) {
charArray3[j] = '\0';
}

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
charArray4[0] = (charArray3[0] & MASK_0X_FC) >> SHIFT_2;
charArray4[1] = ((charArray3[0] & MASK_0X03) << SHIFT_4) +
((charArray3[1] & MASK_0X_F0) >> SHIFT_4);
charArray4[2] = ((charArray3[1] & MASK_0X0_F) << SHIFT_2) +
((charArray3[2] & MASK_0X_C0) >> SHIFT_6);
charArray4[3] = charArray3[2] & MASK_0X3_F;

for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
for (int j = 0; j < index3 + 1; j++) {
result += BASE64_CHARS[charArray4[j]];
}

while ((i++ < 3))
ret += '=';
while (index3++ < 3) {
result += '=';
}
}

return ret;
return result;
}

static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
static inline auto isBase64(unsigned char character) -> bool {
return ((isalnum(character) != 0) || (character == '+') ||
(character == '/'));
}

std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;

while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
auto base64Decode(std::string const& encoded_string) -> std::string {
std::size_t inputLength = encoded_string.size();
int index3 = 0;
int inputIndex = 0;
std::array<unsigned char, 4> charArray4;
std::array<unsigned char, 3> charArray3;
std::string result;

while (((inputLength--) != 0) && (encoded_string[inputIndex] != '=') &&
isBase64(encoded_string[inputIndex])) {
charArray4[index3++] = encoded_string[inputIndex];
inputIndex++;
if (index3 == 4) {
for (index3 = 0; index3 < 4; index3++) {
charArray4[index3] = BASE64_CHARS.find(charArray4[index3]);
}

charArray3[0] = (charArray4[0] << SHIFT_2) +
((charArray4[1] & MASK_0X30) >> SHIFT_4);
charArray3[1] = ((charArray4[1] & MASK_0X0_F) << SHIFT_4) +
((charArray4[2] & MASK_0X3_C) >> SHIFT_2);
charArray3[2] =
((charArray4[2] & MASK_0X03) << SHIFT_6) + charArray4[3];

for (index3 = 0; index3 < 3; index3++) {
result += charArray3[index3];
}
index3 = 0;
}
}

if (i) {
for (j = 0; j < i; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
if (index3 != 0) {
for (int j = 0; j < index3; j++) {
charArray4[j] = BASE64_CHARS.find(charArray4[j]);
}

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
charArray3[0] = (charArray4[0] << SHIFT_2) +
((charArray4[1] & MASK_0X30) >> SHIFT_4);
charArray3[1] = ((charArray4[1] & MASK_0X0_F) << SHIFT_4) +
((charArray4[2] & MASK_0X3_C) >> SHIFT_2);
charArray3[2] =
((charArray4[2] & MASK_0X03) << SHIFT_6) + charArray4[3];

for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
for (int j = 0; j < index3 - 1; j++) {
result += charArray3[j];
}
}

return ret;
}
return result;
}
Loading

0 comments on commit 529fc4b

Please sign in to comment.