added jpeg support

This commit is contained in:
vaxerski 2022-07-04 12:51:15 +02:00
parent fdaea3d78a
commit 7b87336d45
5 changed files with 90 additions and 9 deletions

View file

@ -35,8 +35,4 @@ You can use `hyprctl hyprpaper` (if on Hyprland) to issue a keyword, for example
hyprctl hyprpaper wallpaper DP-1,~/Pictures/myepicpng.png
```
For other compositors, the socket works like socket1 of Hyprland, and is located in `/tmp/hypr/.hyprpaper.sock` (this path only when Hyprland is not running!)
# todos
- jpeg support
For other compositors, the socket works like socket1 of Hyprland, and is located in `/tmp/hypr/.hyprpaper.sock` (this path only when Hyprland is not running!)

75
src/helpers/Jpeg.cpp Normal file
View file

@ -0,0 +1,75 @@
#include "Jpeg.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
#error "your system is not little endian, jpeg will not work, ping vaxry or something"
#endif
cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
if (!std::filesystem::exists(path)) {
Debug::log(ERR, "createSurfaceFromJPEG: file doesn't exist??");
exit(1);
}
if (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) {
Debug::log(CRIT, "tried to load a jpeg on a big endian system! ping vaxry he is lazy.");
exit(1);
}
void* imageRawData;
struct stat fileInfo;
const auto FD = open(path.c_str(), O_RDONLY);
fstat(FD, &fileInfo);
imageRawData = malloc(fileInfo.st_size);
read(FD, imageRawData, fileInfo.st_size);
close(FD);
// now the JPEG is in the memory
jpeg_decompress_struct decompressStruct;
jpeg_error_mgr errorManager;
decompressStruct.err = jpeg_std_error(&errorManager);
jpeg_create_decompress(&decompressStruct);
jpeg_mem_src(&decompressStruct, (const unsigned char*)imageRawData, fileInfo.st_size);
jpeg_read_header(&decompressStruct, true);
decompressStruct.out_color_space = JCS_EXT_BGRA;
// decompress
jpeg_start_decompress(&decompressStruct);
auto cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, decompressStruct.output_width, decompressStruct.output_height);
if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) {
Debug::log(ERR, "createSurfaceFromJPEG: Cairo Failed (?)");
exit(1);
}
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
JSAMPROW rowRead;
while (decompressStruct.output_scanline < decompressStruct.output_height) {
const auto PROW = CAIRODATA + (decompressStruct.output_scanline * CAIROSTRIDE);
rowRead = PROW;
jpeg_read_scanlines(&decompressStruct, &rowRead, 1);
}
cairo_surface_mark_dirty(cairoSurface);
cairo_surface_set_mime_data(cairoSurface, CAIRO_MIME_TYPE_JPEG, (const unsigned char*)imageRawData, fileInfo.st_size, free, imageRawData);
jpeg_finish_decompress(&decompressStruct);
jpeg_destroy_decompress(&decompressStruct);
return cairoSurface;
}

8
src/helpers/Jpeg.hpp Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include "../defines.hpp"
#include <jpeglib.h>
namespace JPEG {
cairo_surface_t* createSurfaceFromJPEG(const std::string&);
};

View file

@ -9,9 +9,8 @@ void CWallpaperTarget::create(const std::string& path) {
if (path.find(".png") == path.length() - 4) {
CAIROSURFACE = cairo_image_surface_create_from_png(path.c_str());
} else if (path.find(".jpg") == path.length() - 4 || path.find(".jpeg") == path.length() - 5) {
Debug::log(ERR, ".jpg images are not yet supported! :(");
exit(1);
return;
CAIROSURFACE = JPEG::createSurfaceFromJPEG(path);
m_bHasAlpha = false;
} else {
Debug::log(CRIT, "unrecognized image %s", path.c_str());
exit(1);

View file

@ -1,6 +1,7 @@
#pragma once
#include "../defines.hpp"
#include "../helpers/Jpeg.hpp"
class CWallpaperTarget {
public:
@ -10,7 +11,9 @@ public:
std::string m_szPath;
Vector2D m_vSize;
Vector2D m_vSize;
bool m_bHasAlpha = true;
cairo_surface_t* m_pCairoSurface;
};