Initial Cross Platform Work

This commit is contained in:
2025-04-24 16:39:24 +02:00
parent dbffb7f316
commit 13c2869ba8
170 changed files with 18611 additions and 10292 deletions

View File

@ -22,6 +22,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifdef PD_IMAGE_BUILD_SHARED
#define STB_IMAGE_IMPLEMENTATION
#endif
#include <pd/external/stb_image.h>
#include <cstring>
@ -30,31 +34,121 @@ SOFTWARE.
#include <pd/image/img_convert.hpp>
namespace PD {
void Image::Load(const std::string& path) {
u8* img = stbi_load(path.c_str(), &w, &h, &fmt, 4);
PD_IMAGE_API void Image::Load(const std::string& path) {
u8* img = stbi_load(path.c_str(), &pWidth, &pHeight, &fmt, 4);
if (fmt == 3) {
stbi_image_free(img);
img = stbi_load(path.c_str(), &w, &h, &fmt, 3);
buffer.resize(w * h * 4);
PD::ImgConvert::RGB24toRGBA32(
buffer, std::vector<u8>(img, img + (w * h * 3)), w, h);
} else {
buffer.assign(img, img + (w * h * 4));
img = stbi_load(path.c_str(), &pWidth, &pHeight, &fmt, 3);
pBuffer = std::vector<PD::u8>(img, img + (pWidth * pHeight * 3));
pFmt = RGB;
stbi_image_free(img);
} else if (fmt == 4) {
pBuffer = std::vector<PD::u8>(img, img + (pWidth * pHeight * 4));
pFmt = RGBA;
stbi_image_free(img);
}
}
void Image::Load(const std::vector<u8>& buf) {
u8* img = stbi_load_from_memory(buf.data(), buf.size(), &w, &h, &fmt, 4);
PD_IMAGE_API void Image::Load(const std::vector<u8>& buf) {
u8* img =
stbi_load_from_memory(buf.data(), buf.size(), &pWidth, &pHeight, &fmt, 4);
if (fmt == 3) {
stbi_image_free(img);
img = stbi_load_from_memory(buf.data(), buf.size(), &w, &h, &fmt, 3);
buffer.resize(w * h * 4);
PD::ImgConvert::RGB24toRGBA32(
buffer, std::vector<u8>(img, img + (w * h * 3)), w, h);
} else {
buffer.assign(img, img + (w * h * 4));
img = stbi_load_from_memory(buf.data(), buf.size(), &pWidth, &pHeight, &fmt,
3);
pBuffer = std::vector<PD::u8>(img, img + (pWidth * pHeight * 3));
pFmt = RGB;
stbi_image_free(img);
} else if (fmt == 4) {
pBuffer = std::vector<PD::u8>(img, img + (pWidth * pHeight * 4));
stbi_image_free(img);
pFmt = RGBA;
}
}
PD_IMAGE_API void Image::Copy(const std::vector<u8>& buf, int w, int h,
int bpp) {
this->fmt = bpp;
if (buf.size() != (size_t)w * h * bpp) {
// Size Error
return;
}
this->pBuffer.resize(w * h * bpp);
for (size_t i = 0; i < this->pBuffer.size(); i++) {
pBuffer[i] = buf[i];
}
}
PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
if (img->Fmt() == dst) {
return;
} else if (img->Fmt() == Image::RGB && dst == Image::BGR) {
ImgConvert::ReverseBuf(img->pBuffer, 3, img->pWidth, img->pHeight);
} else if (img->Fmt() == Image::RGB && dst == Image::RGBA) {
std::vector<PD::u8> cpy = img->pBuffer;
img->pBuffer.resize(img->pWidth * img->pHeight * 4);
ImgConvert::RGB24toRGBA32(img->pBuffer, cpy, img->pWidth, img->pHeight);
} else if (img->Fmt() == Image::RGBA && dst == Image::RGB) {
std::vector<PD::u8> cpy = img->pBuffer;
img->pBuffer.resize(img->pWidth * img->pHeight * 3);
ImgConvert::RGB32toRGBA24(img->pBuffer, cpy, img->pWidth, img->pHeight);
} else if (img->Fmt() == Image::RGBA && dst == Image::RGB565) {
Convert(img, Image::RGB);
Convert(img, Image::RGB565);
} else if (img->Fmt() == Image::RGB && dst == Image::RGB565) {
auto f = [](u8 r, u8 g, u8 b) -> u16 {
u16 _r = (r >> 3);
u16 _g = (g >> 2);
u16 _b = (b >> 3);
return (_r << 11) | (_g << 5) | _b;
};
std::vector<PD::u8> cpy = img->pBuffer;
img->pBuffer.resize(img->pWidth * img->pHeight * 2);
for (int y = 0; y < img->pWidth; y++) {
for (int x = 0; x < img->pHeight; x++) {
int src = (y * img->pWidth + x) * 3;
int dst = (y * img->pWidth + x) * 2;
u16 new_px = f(cpy[src + 0], cpy[src + 1], cpy[src + 2]);
img->pBuffer[dst + 0] = new_px >> 8;
img->pBuffer[dst + 1] = new_px & 0xff;
}
}
}
}
PD_IMAGE_API int Image::Fmt2Bpp(Format fmt) {
switch (fmt) {
case RGBA:
case ABGR:
return 4;
break;
case RGB:
case BGR:
return 3;
break;
case RGB565:
return 2;
break;
default:
return 0;
break;
}
}
PD_IMAGE_API void Image::ReTile(Image::Ref img,
std::function<u32(int x, int y, int w)> src,
std::function<u32(int x, int y, int w)> dst) {
std::vector<PD::u8> cpy = img->pBuffer;
/** could use fmt here but for 565 that woulnt work as it is not supported by
* file loading where fmt is used */
int bpp = Fmt2Bpp(img->pFmt);
for (int y = 0; y < img->pHeight; y++) {
for (int x = 0; x < img->pWidth; x++) {
int src_idx = src(x, y, img->pWidth);
int dst_idx = dst(x, y, img->pWidth);
for (int i = 0; i < bpp; i++) {
img->pBuffer[dst_idx + i] = cpy[src_idx + i];
}
}
}
}
void Image::Copy(const std::vector<u8>& buf, int w, int h, int fmt) {}
} // namespace PD

View File

@ -29,7 +29,7 @@ SOFTWARE.
namespace PD {
namespace ImgBlur {
std::vector<float> GaussianKernel(int r, float si) {
PD_IMAGE_API std::vector<float> GaussianKernel(int r, float si) {
/// Define radius as r to be shorter
int size = 2 * r + 1;
std::vector<float> kernel(size);
@ -45,13 +45,15 @@ std::vector<float> GaussianKernel(int r, float si) {
}
return kernel;
}
void GaussianBlur(std::vector<u8> &buf, int w, int h, float radius, float si,
std::function<int(int, int, int)> idxfn) {
PD_IMAGE_API void GaussianBlur(std::vector<u8> &buf, int w, int h, float radius,
float si,
std::function<int(int, int, int)> idxfn) {
GaussianBlur(buf.data(), w, h, 4, radius, si, idxfn);
}
void GaussianBlur(void *buf, int w, int h, int bpp, float radius, float si,
std::function<int(int, int, int)> idxfn) {
PD_IMAGE_API void GaussianBlur(void *buf, int w, int h, int bpp, float radius,
float si,
std::function<int(int, int, int)> idxfn) {
if (bpp != 4 && bpp != 3) {
return;
}

View File

@ -24,8 +24,9 @@ SOFTWARE.
#include <pd/image/img_convert.hpp>
namespace PD::ImgConvert {
void RGB24toRGBA32(std::vector<u8> &out, const std::vector<u8> &in,
const int &w, const int &h) {
PD_IMAGE_API void RGB24toRGBA32(std::vector<u8> &out, const std::vector<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
@ -38,7 +39,22 @@ void RGB24toRGBA32(std::vector<u8> &out, const std::vector<u8> &in,
}
}
}
void Reverse32(std::vector<u8> &buf, const int &w, const int &h) {
PD_IMAGE_API void RGB32toRGBA24(std::vector<u8> &out, const std::vector<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 4;
int dst = (y * w + x) * 3;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
}
}
}
PD_IMAGE_API void Reverse32(std::vector<u8> &buf, const int &w, const int &h) {
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int i = y * w + x;
@ -51,4 +67,71 @@ void Reverse32(std::vector<u8> &buf, const int &w, const int &h) {
}
}
}
PD_IMAGE_API void ReverseBuf(std::vector<u8> &buf, size_t bpp, int w, int h) {
std::vector<u8> cpy = buf;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * bpp;
for (size_t i = 0; i < bpp; i++) {
buf[pos + bpp - 1 - i] = cpy[pos + i];
}
}
}
}
PD_IMAGE_API void RGB24toRGBA32(PD::Vec<u8> &out, const PD::Vec<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 3;
int dst = (y * w + x) * 4;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
out[dst + 3] = 255;
}
}
}
PD_IMAGE_API void RGB32toRGBA24(PD::Vec<u8> &out, const PD::Vec<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 4;
int dst = (y * w + x) * 3;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
}
}
}
PD_IMAGE_API void Reverse32(PD::Vec<u8> &buf, const int &w, const int &h) {
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int i = y * w + x;
u8 t0 = buf[i + 0];
u8 t1 = buf[i + 1];
buf[i + 0] = buf[i + 3];
buf[i + 1] = buf[i + 2];
buf[i + 3] = t0;
buf[i + 2] = t1;
}
}
}
PD_IMAGE_API void ReverseBuf(PD::Vec<u8> &buf, size_t bpp, int w, int h) {
PD::Vec<u8> cpy = buf;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * bpp;
for (size_t i = 0; i < bpp; i++) {
buf[pos + bpp - 1 - i] = cpy[pos + i];
}
}
}
}
} // namespace PD::ImgConvert