// imagemagick plugins const std = @import("std"); const images = @import("image.zig"); const Image = images.Image; const mc = @cImport({ @cInclude("MagickWand/MagickWand.h"); }); pub const MagickContext = struct { wand: *mc.MagickWand, pub fn init() !MagickContext { mc.MagickWandGenesis(); var wand = mc.NewMagickWand(); if (wand == null) return error.WandCreateFail; return MagickContext{ .wand = wand.?, }; } pub fn deinit(self: *MagickContext) void { _ = mc.DestroyMagickWand(self.wand); mc.MagickWandTerminus(); } pub fn doErr(self: *MagickContext) !void { return error.WandError; } }; fn magickLoad(image: *Image) !MagickContext { var mctx = try MagickContext.init(); errdefer mctx.deinit(); var curpath = try std.cstr.addNullByte(image.allocator, image.curpath); defer image.allocator.free(curpath); if (mc.MagickReadImage(mctx.wand, curpath.ptr) == .MagickFalse) return error.MagickReadFail; return mctx; } fn magickSave(image: *Image, mctx: *MagickContext) !void { var tmpnam = try images.temporaryName(image.allocator); defer image.allocator.free(tmpnam); var c_tmpnam = try std.cstr.addNullByte(image.allocator, tmpnam); defer image.allocator.free(c_tmpnam); std.debug.warn( "\tmagick: saving from '{}' to '{}'\n", image.curpath, c_tmpnam, ); if (mc.MagickWriteImages(mctx.wand, c_tmpnam.ptr, .MagickTrue) == .MagickFalse) return error.MagickWriteFail; } pub fn runRotate(image: *Image) !void { var mctx = try magickLoad(image); defer mctx.deinit(); // TODO run rotate here try magickSave(image, &mctx); }