magick.d 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * pixiv_down - CLI-based downloading tool for https://www.pixiv.net.
  3. * Copyright (C) 2023, 2024 Mio
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. */
  17. module pd.imaging.magick;
  18. import core.stdc.config : c_ulong;
  19. alias MagickWand = void;
  20. mixin template GenBinding(string FunctionName, string FunctionSignature)
  21. {
  22. mixin("alias _" ~ FunctionName ~ " = nothrow extern(C) @system @nogc " ~ FunctionSignature ~ ";");
  23. mixin("__gshared _" ~ FunctionName ~ " " ~ FunctionName ~ ";");
  24. }
  25. template GenMagickSym(string FunctionName)
  26. {
  27. const char[] GenMagickSym = FunctionName ~ " = cast(typeof("~FunctionName~"))dlsym(libMagick, \""~FunctionName~"\");
  28. if ((errmsg = dlerror()) !is null) {
  29. fprintf(stderr, \"Failed to bind symbol: %s\\n\", errmsg);
  30. dlerror();
  31. }";
  32. }
  33. template GenWandSym(string FunctionName)
  34. {
  35. const char[] GenWandSym = FunctionName ~ " = cast(typeof("~FunctionName~"))dlsym(libWand, \""~FunctionName~"\");
  36. if ((errmsg = dlerror()) !is null) {
  37. fprintf(stderr, \"Failed to bind symbol: %s\\n\", errmsg);
  38. dlerror();
  39. }";
  40. }
  41. // GraphicsMagick
  42. mixin GenBinding!("InitializeMagick", "void function(const char*)");
  43. mixin GenBinding!("DestroyMagick", "void function()");
  44. mixin GenBinding!("GetMagickVersion", "char* function(c_ulong*)");
  45. // GraphicsMagickWand
  46. mixin GenBinding!("CloneMagickWand", "MagickWand* function(MagickWand*)");
  47. mixin GenBinding!("DestroyMagickWand", "void function(MagickWand*)");
  48. mixin GenBinding!("MagickAddImage", "uint function(MagickWand*, MagickWand*)");
  49. mixin GenBinding!("MagickGetImageFilename", "char* function(MagickWand*)");
  50. mixin GenBinding!("MagickGetNumberImages", "c_ulong function(MagickWand*)");
  51. mixin GenBinding!("MagickNextImage", "uint function(MagickWand*)");
  52. mixin GenBinding!("MagickReadImage", "uint function(MagickWand*, const char*)");
  53. mixin GenBinding!("MagickResetIterator", "void function(MagickWand*)");
  54. mixin GenBinding!("MagickSetImageDelay", "uint function(MagickWand*, c_ulong)");
  55. mixin GenBinding!("MagickSetImageDispose", "uint function(MagickWand*, int)");
  56. mixin GenBinding!("MagickSetImageFormat", "uint function(MagickWand*, const char*)");
  57. mixin GenBinding!("MagickSetImageIterations", "uint function(MagickWand*, int)");
  58. mixin GenBinding!("MagickSetImageIndex", "uint function(MagickWand*, c_ulong)");
  59. mixin GenBinding!("MagickWriteImages", "uint function(MagickWand*, const char*, uint)");
  60. mixin GenBinding!("NewMagickWand", "MagickWand* function()");
  61. // Based off of GM -- TODO: check IM
  62. enum PreviousDispose = 3;
  63. void loadMagick(string programName)
  64. {
  65. import core.sys.posix.dlfcn;
  66. import core.stdc.stdio;
  67. import std.experimental.logger;
  68. import std.string : toStringz, fromStringz;
  69. void* libMagick = dlopen("libGraphicsMagick.so", RTLD_LAZY);
  70. if (null is libMagick) {
  71. // TODO: handle error
  72. critical(fromStringz(dlerror()));
  73. }
  74. void* libWand = dlopen("libGraphicsMagickWand.so", RTLD_LAZY);
  75. if (null is libWand) {
  76. // TODO: handle error
  77. critical(fromStringz(dlerror()));
  78. }
  79. dlerror();
  80. char* errmsg;
  81. mixin(GenMagickSym!("InitializeMagick"));
  82. mixin(GenMagickSym!("DestroyMagick"));
  83. mixin(GenMagickSym!("GetMagickVersion"));
  84. mixin(GenWandSym!("CloneMagickWand"));
  85. mixin(GenWandSym!("DestroyMagickWand"));
  86. mixin(GenWandSym!("MagickAddImage"));
  87. mixin(GenWandSym!("MagickGetImageFilename"));
  88. mixin(GenWandSym!("MagickGetNumberImages"));
  89. mixin(GenWandSym!("MagickNextImage"));
  90. mixin(GenWandSym!("MagickReadImage"));
  91. mixin(GenWandSym!("MagickResetIterator"));
  92. mixin(GenWandSym!("MagickSetImageDelay"));
  93. mixin(GenWandSym!("MagickSetImageDispose"));
  94. mixin(GenWandSym!("MagickSetImageFormat"));
  95. mixin(GenWandSym!("MagickSetImageIndex"));
  96. mixin(GenWandSym!("MagickSetImageIterations"));
  97. mixin(GenWandSym!("MagickWriteImages"));
  98. mixin(GenWandSym!("NewMagickWand"));
  99. InitializeMagick(programName.toStringz);
  100. }
  101. void destroyMagick()
  102. {
  103. DestroyMagick();
  104. }
  105. void SetImageDispose(MagickWand* wand, int type)
  106. {
  107. // TODO: Check for IM
  108. MagickSetImageDispose(wand, type);
  109. }