Merge branch 'image-better'
This commit is contained in:
commit
0bb891a18b
3 changed files with 58 additions and 26 deletions
|
|
@ -457,7 +457,7 @@ pub fn renderWallpaper(output: *Output) !void {
|
|||
}
|
||||
// Scale our loaded image and then copy it into the Buffer's pixman.Image
|
||||
const wallpaper_image = context.wallpaper_image orelse return error.MissingWallpaperImage;
|
||||
const image = wallpaper_image.image;
|
||||
const image = wallpaper_image.pix_image;
|
||||
const image_data = image.getData();
|
||||
const image_width = image.getWidth();
|
||||
const image_height = image.getHeight();
|
||||
|
|
|
|||
|
|
@ -4,8 +4,15 @@
|
|||
|
||||
const WallpaperImage = @This();
|
||||
|
||||
image: *pixman.Image,
|
||||
pixels: std.ArrayList(u32),
|
||||
// This is used as the backing store for the pixman image
|
||||
// It's the actual image (png, jpeg, etc.) decoded into pixels.
|
||||
zigimg_image: zigimg.Image,
|
||||
// Only used on big-endian; holds manually converted ARGB pixel data.
|
||||
// On BE: std.ArrayList(u32), on LE: void
|
||||
argb_pixels: if (native_endian == .big) std.ArrayList(u32) else void = if (native_endian == .big) .empty else {},
|
||||
|
||||
// This is the actual scaled, transformed, and rendered image
|
||||
pix_image: *pixman.Image,
|
||||
|
||||
// TODO: Make image_path nullable, if null, do a single color with a single_pixel_buffer instead(?)
|
||||
pub fn create(image_path: []const u8) !*WallpaperImage {
|
||||
|
|
@ -13,44 +20,69 @@ pub fn create(image_path: []const u8) !*WallpaperImage {
|
|||
errdefer utils.gpa.destroy(wallpaper_image);
|
||||
|
||||
var read_buf: [zigimg.io.DEFAULT_BUFFER_SIZE]u8 = undefined;
|
||||
var image = try zigimg.Image.fromFilePath(utils.gpa, image_path, &read_buf);
|
||||
defer image.deinit(utils.gpa);
|
||||
wallpaper_image.zigimg_image = try zigimg.Image.fromFilePath(utils.gpa, image_path, &read_buf);
|
||||
errdefer wallpaper_image.zigimg_image.deinit(utils.gpa);
|
||||
|
||||
// We don't want to deal with all the possible formats,
|
||||
// so let's just convert to one we can use with pixman.
|
||||
if (image.pixelFormat() != .rgba32) {
|
||||
try image.convert(utils.gpa, .rgba32);
|
||||
if (wallpaper_image.zigimg_image.pixelFormat() != .rgba32) {
|
||||
try wallpaper_image.zigimg_image.convert(utils.gpa, .rgba32);
|
||||
}
|
||||
|
||||
log.debug("image loaded ({}x{})", .{ image.width, image.height });
|
||||
log.debug("image loaded ({}x{})", .{ wallpaper_image.zigimg_image.width, wallpaper_image.zigimg_image.height });
|
||||
|
||||
const pixels = image.pixels.rgba32;
|
||||
// We have to manually convert to argb --
|
||||
// It's only guaranteed that Wayland compositors will have xrgb and argb support but zigimg doesn't have either of those.
|
||||
wallpaper_image.pixels = try std.ArrayList(u32).initCapacity(utils.gpa, pixels.len);
|
||||
errdefer wallpaper_image.pixels.deinit(utils.gpa);
|
||||
for (0..pixels.len) |i| {
|
||||
const a: u32 = @intCast(pixels[i].a);
|
||||
const r: u32 = @intCast(pixels[i].r);
|
||||
const g: u32 = @intCast(pixels[i].g);
|
||||
const b: u32 = @intCast(pixels[i].b);
|
||||
const new_val: u32 = (a << 24) + (r << 16) + (g << 8) + b;
|
||||
wallpaper_image.pixels.appendAssumeCapacity(new_val);
|
||||
const pixels = wallpaper_image.zigimg_image.pixels.rgba32;
|
||||
const width: c_int = @intCast(wallpaper_image.zigimg_image.width);
|
||||
const height: c_int = @intCast(wallpaper_image.zigimg_image.height);
|
||||
const stride: c_int = @intCast(wallpaper_image.zigimg_image.width * wallpaper_image.zigimg_image.pixelFormat().pixelStride());
|
||||
|
||||
// zigimg's Rgba32 is an extern struct {r, g, b, a}, which actually matches pixman's a8b8g8r8
|
||||
// (u32 with R at bits 0-7, A at bits 24-31) on little endian machines. That means we can actually
|
||||
// use zigimg's pixel data directly. On big-endian we keep the manual conversion I used to use.
|
||||
switch (native_endian) {
|
||||
.little => {
|
||||
wallpaper_image.pix_image = pixman.Image.createBits(
|
||||
.a8b8g8r8,
|
||||
width,
|
||||
height,
|
||||
@ptrCast(@alignCast(pixels.ptr)),
|
||||
stride,
|
||||
) orelse return error.FailedToCreatePixmanImage;
|
||||
},
|
||||
.big => {
|
||||
wallpaper_image.argb_pixels = try std.ArrayList(u32).initCapacity(utils.gpa, pixels.len);
|
||||
errdefer wallpaper_image.argb_pixels.deinit(utils.gpa);
|
||||
for (pixels) |px| {
|
||||
const a: u32 = px.a;
|
||||
const r: u32 = px.r;
|
||||
const g: u32 = px.g;
|
||||
const b: u32 = px.b;
|
||||
wallpaper_image.argb_pixels.appendAssumeCapacity((a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
wallpaper_image.pix_image = pixman.Image.createBits(
|
||||
.a8r8g8b8,
|
||||
width,
|
||||
height,
|
||||
@ptrCast(@alignCast(wallpaper_image.argb_pixels.items.ptr)),
|
||||
stride,
|
||||
) orelse return error.FailedToCreatePixmanImage;
|
||||
},
|
||||
}
|
||||
|
||||
wallpaper_image.image = pixman.Image.createBits(.a8r8g8b8, @intCast(image.width), @intCast(image.height), @ptrCast(@alignCast(wallpaper_image.pixels.items.ptr)), @intCast(image.width * image.pixelFormat().pixelStride())) orelse return error.FailedToCreatePixmanImage;
|
||||
|
||||
return wallpaper_image;
|
||||
}
|
||||
|
||||
pub fn destroy(wallpaper_image: *WallpaperImage) void {
|
||||
_ = wallpaper_image.image.unref();
|
||||
wallpaper_image.pixels.deinit(utils.gpa);
|
||||
_ = wallpaper_image.pix_image.unref();
|
||||
if (native_endian == .big) wallpaper_image.argb_pixels.deinit(utils.gpa);
|
||||
wallpaper_image.zigimg_image.deinit(utils.gpa);
|
||||
|
||||
utils.gpa.destroy(wallpaper_image);
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const native_endian = builtin.cpu.arch.endian();
|
||||
|
||||
const pixman = @import("pixman");
|
||||
const zigimg = @import("zigimg");
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@ pub fn tokenizeToOwnedSlices(input: []const u8, delimiter: u8) ![][]const u8 {
|
|||
var it = std.mem.tokenizeScalar(u8, input, delimiter);
|
||||
while (it.next()) |part| {
|
||||
const duped = try gpa.dupe(u8, part);
|
||||
try list.append(utils.gpa, duped);
|
||||
try list.append(gpa, duped);
|
||||
}
|
||||
return list.toOwnedSlice(utils.gpa);
|
||||
return list.toOwnedSlice(gpa);
|
||||
}
|
||||
|
||||
pub fn stripQuotes(s: []const u8) []const u8 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue