mediaMachineAPI.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2019 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. #define DFPSR_INTERNAL_ACCESS
  24. #include "mediaMachineAPI.h"
  25. #include "../machine/VirtualMachine.h"
  26. #include "../machine/mediaFilters.h"
  27. #include "../api/imageAPI.h"
  28. namespace dsr {
  29. // Media Machine specification
  30. // Enumerating types
  31. static const DataType DataType_ImageU8 = 1;
  32. static const DataType DataType_ImageRgbaU8 = 2;
  33. static ReadableString getMediaTypeName(DataType type) {
  34. switch(type) {
  35. case DataType_FixedPoint: return U"FixedPoint";
  36. case DataType_ImageU8: return U"ImageU8";
  37. case DataType_ImageRgbaU8: return U"ImageRgbaU8";
  38. default: return U"?";
  39. }
  40. }
  41. class MediaMemory : public PlanarMemory {
  42. public:
  43. MemoryPlane<FixedPoint> FixedPointMemory;
  44. MemoryPlane<AlignedImageU8> AlignedImageU8Memory;
  45. MemoryPlane<OrderedImageRgbaU8> OrderedImageRgbaU8Memory;
  46. MediaMemory() : FixedPointMemory(1024), AlignedImageU8Memory(1024), OrderedImageRgbaU8Memory(512) {}
  47. void store(int targetStackIndex, const VMA& sourceArg, int sourceFramePointer, DataType type) override {
  48. switch(type) {
  49. case DataType_FixedPoint:
  50. if (sourceArg.argType == ArgumentType::Immediate) {
  51. this->FixedPointMemory.accessByStackIndex(targetStackIndex) = sourceArg.value;
  52. } else {
  53. this->FixedPointMemory.accessByStackIndex(targetStackIndex) = this->FixedPointMemory.accessByGlobalIndex(sourceArg.value.getMantissa(), sourceFramePointer);
  54. }
  55. break;
  56. case DataType_ImageU8:
  57. this->AlignedImageU8Memory.accessByStackIndex(targetStackIndex) = this->AlignedImageU8Memory.accessByGlobalIndex(sourceArg.value.getMantissa(), sourceFramePointer);
  58. break;
  59. case DataType_ImageRgbaU8:
  60. this->OrderedImageRgbaU8Memory.accessByStackIndex(targetStackIndex) = this->OrderedImageRgbaU8Memory.accessByGlobalIndex(sourceArg.value.getMantissa(), sourceFramePointer);
  61. break;
  62. default:
  63. throwError("Storing element of unhandled type!\n");
  64. break;
  65. }
  66. }
  67. void load(int sourceStackIndex, const VMA& targetArg, int targetFramePointer, DataType type) override {
  68. switch(type) {
  69. case DataType_FixedPoint:
  70. this->FixedPointMemory.accessByGlobalIndex(targetArg.value.getMantissa(), targetFramePointer) = this->FixedPointMemory.accessByStackIndex(sourceStackIndex);
  71. break;
  72. case DataType_ImageU8:
  73. this->AlignedImageU8Memory.accessByGlobalIndex(targetArg.value.getMantissa(), targetFramePointer) = this->AlignedImageU8Memory.accessByStackIndex(sourceStackIndex);
  74. break;
  75. case DataType_ImageRgbaU8:
  76. this->OrderedImageRgbaU8Memory.accessByGlobalIndex(targetArg.value.getMantissa(), targetFramePointer) = this->OrderedImageRgbaU8Memory.accessByStackIndex(sourceStackIndex);
  77. break;
  78. default:
  79. throwError("Loading element of unhandled type!\n");
  80. break;
  81. }
  82. }
  83. };
  84. #define MEDIA_MEMORY ((MediaMemory&)memory)
  85. // Type definitions
  86. static const VMTypeDef mediaMachineTypes[] = {
  87. VMTypeDef(U"FixedPoint", DataType_FixedPoint, true,
  88. [](VirtualMachine& machine, int globalIndex, const ReadableString& defaultValueText){
  89. FixedPoint defaultValue = string_length(defaultValueText) > 0 ? FixedPoint::fromText(defaultValueText) : FixedPoint();
  90. List<VMA> args;
  91. args.pushConstruct(DataType_FixedPoint, globalIndex);
  92. args.pushConstruct(defaultValue);
  93. machine.interpretCommand(U"Load", args);
  94. },
  95. [](PlanarMemory& memory, Variable& variable, int globalIndex, int32_t* framePointer, bool fullContent) {
  96. FixedPoint value = MEDIA_MEMORY.FixedPointMemory.accessByGlobalIndex(globalIndex, framePointer[DataType_FixedPoint]);
  97. printText(variable.name, "(", value, ")");
  98. }),
  99. VMTypeDef(U"ImageU8", DataType_ImageU8, false,
  100. [](VirtualMachine& machine, int globalIndex, const ReadableString& defaultValueText){
  101. List<VMA> args;
  102. args.pushConstruct(DataType_ImageU8, globalIndex);
  103. machine.interpretCommand(U"Reset", args);
  104. },
  105. [](PlanarMemory& memory, Variable& variable, int globalIndex, int32_t* framePointer, bool fullContent) {
  106. AlignedImageU8 value = MEDIA_MEMORY.AlignedImageU8Memory.accessByGlobalIndex(globalIndex, framePointer[DataType_ImageU8]);
  107. printText(variable.name, " ImageU8");
  108. if (image_exists(value)) {
  109. if (fullContent) {
  110. printText(":\n", image_toAscii(value, U" .:*ixXM"));
  111. } else {
  112. printText("(", image_getWidth(value), "x", image_getHeight(value), ")");
  113. }
  114. } else {
  115. printText("(nothing)");
  116. }
  117. }),
  118. VMTypeDef(U"ImageRgbaU8", DataType_ImageRgbaU8, false,
  119. [](VirtualMachine& machine, int globalIndex, const ReadableString& defaultValueText){
  120. List<VMA> args;
  121. args.pushConstruct(DataType_ImageRgbaU8, globalIndex);
  122. machine.interpretCommand(U"Reset", args);
  123. },
  124. [](PlanarMemory& memory, Variable& variable, int globalIndex, int32_t* framePointer, bool fullContent) {
  125. OrderedImageRgbaU8 value = MEDIA_MEMORY.OrderedImageRgbaU8Memory.accessByGlobalIndex(globalIndex, framePointer[DataType_ImageRgbaU8]);
  126. printText(variable.name, " ImageRgbaU8");
  127. if (image_exists(value)) {
  128. // TODO: image_toAscii for multi-channel images
  129. printText("(", image_getWidth(value), "x", image_getHeight(value), ")");
  130. } else {
  131. printText("(nothing)");
  132. }
  133. })
  134. };
  135. inline FixedPoint getFixedPointValue(MediaMemory& memory, const VMA& arg) {
  136. if (arg.argType == ArgumentType::Immediate) {
  137. return arg.value;
  138. } else {
  139. return memory.FixedPointMemory.getRef(arg, memory.current.framePointer[DataType_FixedPoint]);
  140. }
  141. }
  142. #define SCALAR_VALUE(ARG_INDEX) getFixedPointValue(MEDIA_MEMORY, args[ARG_INDEX])
  143. #define INT_VALUE(ARG_INDEX) fixedPoint_round(SCALAR_VALUE(ARG_INDEX))
  144. #define SCALAR_REF(ARG_INDEX) (MEDIA_MEMORY.FixedPointMemory.getRef(args[ARG_INDEX], memory.current.framePointer[DataType_FixedPoint]))
  145. #define IMAGE_U8_REF(ARG_INDEX) (MEDIA_MEMORY.AlignedImageU8Memory.getRef(args[ARG_INDEX], memory.current.framePointer[DataType_ImageU8]))
  146. #define IMAGE_RGBAU8_REF(ARG_INDEX) (MEDIA_MEMORY.OrderedImageRgbaU8Memory.getRef(args[ARG_INDEX], memory.current.framePointer[DataType_ImageRgbaU8]))
  147. #define NEXT_INSTRUCTION memory.current.programCounter++;
  148. static const InsSig mediaMachineInstructions[] = {
  149. InsSig::create(U"LOAD", 1,
  150. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  151. SCALAR_REF(0) = SCALAR_VALUE(1);
  152. NEXT_INSTRUCTION
  153. },
  154. ArgSig(U"Target", false, DataType_FixedPoint),
  155. ArgSig(U"Source", true, DataType_FixedPoint)
  156. ),
  157. InsSig::create(U"RESET", 1,
  158. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  159. IMAGE_U8_REF(0) = AlignedImageU8();
  160. NEXT_INSTRUCTION
  161. },
  162. ArgSig(U"Target", false, DataType_ImageU8)
  163. ),
  164. InsSig::create(U"RESET", 1,
  165. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  166. IMAGE_RGBAU8_REF(0) = OrderedImageRgbaU8();
  167. NEXT_INSTRUCTION
  168. },
  169. ArgSig(U"Target", false, DataType_ImageRgbaU8)
  170. ),
  171. InsSig::create(U"ROUND", 1,
  172. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  173. SCALAR_REF(0) = FixedPoint::fromWhole(fixedPoint_round(SCALAR_VALUE(1)));
  174. NEXT_INSTRUCTION
  175. },
  176. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  177. ArgSig(U"Source", true, DataType_FixedPoint)
  178. ),
  179. InsSig::create(U"MIN", 1,
  180. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  181. SCALAR_REF(0) = fixedPoint_min(SCALAR_VALUE(1), SCALAR_VALUE(2));
  182. NEXT_INSTRUCTION
  183. },
  184. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  185. ArgSig(U"LeftSource", true, DataType_FixedPoint),
  186. ArgSig(U"RightSource", true, DataType_FixedPoint)
  187. ),
  188. InsSig::create(U"MAX", 1,
  189. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  190. SCALAR_REF(0) = fixedPoint_max(SCALAR_VALUE(1), SCALAR_VALUE(2));
  191. NEXT_INSTRUCTION
  192. },
  193. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  194. ArgSig(U"LeftSource", true, DataType_FixedPoint),
  195. ArgSig(U"RightSource", true, DataType_FixedPoint)
  196. ),
  197. InsSig::create(U"ADD", 1,
  198. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  199. SCALAR_REF(0) = SCALAR_VALUE(1) + SCALAR_VALUE(2);
  200. NEXT_INSTRUCTION
  201. },
  202. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  203. ArgSig(U"LeftSource", true, DataType_FixedPoint),
  204. ArgSig(U"RightSource", true, DataType_FixedPoint)
  205. ),
  206. InsSig::create(U"ADD", 1,
  207. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  208. media_filter_add(IMAGE_U8_REF(0), IMAGE_U8_REF(1), IMAGE_U8_REF(2));
  209. NEXT_INSTRUCTION
  210. },
  211. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  212. ArgSig(U"LeftSource", true, DataType_ImageU8),
  213. ArgSig(U"RightSource", true, DataType_ImageU8)
  214. ),
  215. InsSig::create(U"ADD", 1,
  216. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  217. media_filter_add(IMAGE_U8_REF(0), IMAGE_U8_REF(1), SCALAR_VALUE(2));
  218. NEXT_INSTRUCTION
  219. },
  220. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  221. ArgSig(U"LeftSource", true, DataType_ImageU8),
  222. ArgSig(U"RightSource", true, DataType_FixedPoint)
  223. ),
  224. InsSig::create(U"ADD", 1,
  225. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  226. media_filter_add(IMAGE_U8_REF(0), IMAGE_U8_REF(2), SCALAR_VALUE(1));
  227. NEXT_INSTRUCTION
  228. },
  229. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  230. ArgSig(U"LeftSource", true, DataType_FixedPoint),
  231. ArgSig(U"RightSource", true, DataType_ImageU8)
  232. ),
  233. InsSig::create(U"SUB", 1,
  234. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  235. SCALAR_REF(0) = SCALAR_VALUE(1) - SCALAR_VALUE(2);
  236. NEXT_INSTRUCTION
  237. },
  238. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  239. ArgSig(U"PositiveSource", true, DataType_FixedPoint),
  240. ArgSig(U"NegativeSource", true, DataType_FixedPoint)
  241. ),
  242. InsSig::create(U"SUB", 1,
  243. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  244. media_filter_sub(IMAGE_U8_REF(0), IMAGE_U8_REF(1), IMAGE_U8_REF(2));
  245. NEXT_INSTRUCTION
  246. },
  247. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  248. ArgSig(U"PositiveSource", true, DataType_ImageU8),
  249. ArgSig(U"NegativeSource", true, DataType_ImageU8)
  250. ),
  251. InsSig::create(U"SUB", 1,
  252. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  253. media_filter_sub(IMAGE_U8_REF(0), IMAGE_U8_REF(1), SCALAR_VALUE(2));
  254. NEXT_INSTRUCTION
  255. },
  256. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  257. ArgSig(U"PositiveSource", true, DataType_ImageU8),
  258. ArgSig(U"NegativeSource", true, DataType_FixedPoint)
  259. ),
  260. InsSig::create(U"SUB", 1,
  261. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  262. media_filter_sub(IMAGE_U8_REF(0), SCALAR_VALUE(2), IMAGE_U8_REF(1));
  263. NEXT_INSTRUCTION
  264. },
  265. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  266. ArgSig(U"PositiveSource", true, DataType_FixedPoint),
  267. ArgSig(U"NegativeSource", true, DataType_ImageU8)
  268. ),
  269. InsSig::create(U"MUL", 1,
  270. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  271. SCALAR_REF(0) = SCALAR_VALUE(1) * SCALAR_VALUE(2);
  272. NEXT_INSTRUCTION
  273. },
  274. ArgSig(U"Target", false, DataType_FixedPoint), // Aliasing is accepted
  275. ArgSig(U"LeftSource", true, DataType_FixedPoint),
  276. ArgSig(U"RightSource", true, DataType_FixedPoint)
  277. ),
  278. InsSig::create(U"MUL", 1,
  279. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  280. media_filter_mul(IMAGE_U8_REF(0), IMAGE_U8_REF(1), SCALAR_VALUE(2));
  281. NEXT_INSTRUCTION
  282. },
  283. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  284. ArgSig(U"LeftSource", true, DataType_ImageU8),
  285. ArgSig(U"RightSource", true, DataType_FixedPoint)
  286. ),
  287. InsSig::create(U"MUL", 1,
  288. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  289. media_filter_mul(IMAGE_U8_REF(0), IMAGE_U8_REF(1), IMAGE_U8_REF(2), SCALAR_VALUE(3));
  290. NEXT_INSTRUCTION
  291. },
  292. ArgSig(U"Target", false, DataType_ImageU8), // Aliasing is accepted
  293. ArgSig(U"FirstSource", true, DataType_ImageU8),
  294. ArgSig(U"SecondSource", true, DataType_ImageU8),
  295. ArgSig(U"Scalar", true, DataType_FixedPoint) // Use 1/255 for normalized multiplication
  296. ),
  297. InsSig::create(U"CREATE", 1,
  298. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  299. int width = INT_VALUE(1);
  300. int height = INT_VALUE(2);
  301. if (width < 1 || height < 1) {
  302. throwError("Images must allocate at least one pixel to be created.");
  303. }
  304. IMAGE_U8_REF(0) = image_create_U8(width, height);
  305. NEXT_INSTRUCTION
  306. },
  307. ArgSig(U"Target", false, DataType_ImageU8),
  308. ArgSig(U"Width", true, DataType_FixedPoint),
  309. ArgSig(U"Height", true, DataType_FixedPoint)
  310. ),
  311. InsSig::create(U"CREATE", 1,
  312. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  313. int width = INT_VALUE(1);
  314. int height = INT_VALUE(2);
  315. if (width < 1 || height < 1) {
  316. throwError("Images must allocate at least one pixel to be created.");
  317. }
  318. IMAGE_RGBAU8_REF(0) = image_create_RgbaU8(width, height);
  319. NEXT_INSTRUCTION
  320. },
  321. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  322. ArgSig(U"Width", true, DataType_FixedPoint),
  323. ArgSig(U"Height", true, DataType_FixedPoint)
  324. ),
  325. InsSig::create(U"EXISTS", 1,
  326. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  327. SCALAR_REF(0) = FixedPoint::fromWhole(image_exists(IMAGE_U8_REF(1)) ? 1 : 0);
  328. NEXT_INSTRUCTION
  329. },
  330. ArgSig(U"Truth", false, DataType_FixedPoint), // 1 for existing, 0 for null
  331. ArgSig(U"Source", true, DataType_ImageU8)
  332. ),
  333. InsSig::create(U"EXISTS", 1,
  334. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  335. SCALAR_REF(0) = FixedPoint::fromWhole(image_exists(IMAGE_RGBAU8_REF(1)) ? 1 : 0);
  336. NEXT_INSTRUCTION
  337. },
  338. ArgSig(U"Truth", false, DataType_FixedPoint), // 1 for existing, 0 for null
  339. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  340. ),
  341. InsSig::create(U"GET_WIDTH", 1,
  342. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  343. SCALAR_REF(0) = FixedPoint::fromWhole(image_getWidth(IMAGE_U8_REF(1)));
  344. NEXT_INSTRUCTION
  345. },
  346. ArgSig(U"Width", false, DataType_FixedPoint),
  347. ArgSig(U"Source", true, DataType_ImageU8)
  348. ),
  349. InsSig::create(U"GET_WIDTH", 1,
  350. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  351. SCALAR_REF(0) = FixedPoint::fromWhole(image_getWidth(IMAGE_RGBAU8_REF(1)));
  352. NEXT_INSTRUCTION
  353. },
  354. ArgSig(U"Width", false, DataType_FixedPoint),
  355. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  356. ),
  357. InsSig::create(U"GET_HEIGHT", 1,
  358. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  359. SCALAR_REF(0) = FixedPoint::fromWhole(image_getHeight(IMAGE_U8_REF(1)));
  360. NEXT_INSTRUCTION
  361. },
  362. ArgSig(U"Height", false, DataType_FixedPoint),
  363. ArgSig(U"Source", true, DataType_ImageU8)
  364. ),
  365. InsSig::create(U"GET_HEIGHT", 1,
  366. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  367. SCALAR_REF(0) = FixedPoint::fromWhole(image_getHeight(IMAGE_RGBAU8_REF(1)));
  368. NEXT_INSTRUCTION
  369. },
  370. ArgSig(U"Height", false, DataType_FixedPoint),
  371. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  372. ),
  373. InsSig::create(U"FILL", 1,
  374. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  375. image_fill(IMAGE_U8_REF(0), INT_VALUE(1));
  376. NEXT_INSTRUCTION
  377. },
  378. ArgSig(U"Target", false, DataType_ImageU8),
  379. ArgSig(U"Luma", true, DataType_FixedPoint)
  380. ),
  381. InsSig::create(U"FILL", 1,
  382. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  383. image_fill(
  384. IMAGE_RGBAU8_REF(0),
  385. ColorRgbaI32(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4))
  386. );
  387. NEXT_INSTRUCTION
  388. },
  389. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  390. ArgSig(U"Red", true, DataType_FixedPoint),
  391. ArgSig(U"Green", true, DataType_FixedPoint),
  392. ArgSig(U"Blue", true, DataType_FixedPoint),
  393. ArgSig(U"Alpha", true, DataType_FixedPoint)
  394. ),
  395. InsSig::create(U"RECTANGLE", 1,
  396. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  397. draw_rectangle(
  398. IMAGE_U8_REF(0),
  399. IRect(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4)),
  400. INT_VALUE(5)
  401. );
  402. NEXT_INSTRUCTION
  403. },
  404. ArgSig(U"Target", false, DataType_ImageU8),
  405. ArgSig(U"Left", true, DataType_FixedPoint),
  406. ArgSig(U"Top", true, DataType_FixedPoint),
  407. ArgSig(U"Width", true, DataType_FixedPoint),
  408. ArgSig(U"Height", true, DataType_FixedPoint),
  409. ArgSig(U"Luma", true, DataType_FixedPoint)
  410. ),
  411. InsSig::create(U"RECTANGLE", 1,
  412. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  413. draw_rectangle(
  414. IMAGE_RGBAU8_REF(0),
  415. IRect(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4)),
  416. ColorRgbaI32(INT_VALUE(5), INT_VALUE(6), INT_VALUE(7), INT_VALUE(8))
  417. );
  418. NEXT_INSTRUCTION
  419. },
  420. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  421. ArgSig(U"Left", true, DataType_FixedPoint),
  422. ArgSig(U"Top", true, DataType_FixedPoint),
  423. ArgSig(U"Width", true, DataType_FixedPoint),
  424. ArgSig(U"Height", true, DataType_FixedPoint),
  425. ArgSig(U"Red", true, DataType_FixedPoint),
  426. ArgSig(U"Green", true, DataType_FixedPoint),
  427. ArgSig(U"Blue", true, DataType_FixedPoint),
  428. ArgSig(U"Alpha", true, DataType_FixedPoint)
  429. ),
  430. InsSig::create(U"COPY", 1,
  431. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  432. draw_copy(IMAGE_U8_REF(0), IMAGE_U8_REF(3), INT_VALUE(1), INT_VALUE(2));
  433. NEXT_INSTRUCTION
  434. },
  435. ArgSig(U"Target", false, DataType_ImageU8),
  436. ArgSig(U"TargetLeft", true, DataType_FixedPoint),
  437. ArgSig(U"TargetTop", true, DataType_FixedPoint),
  438. ArgSig(U"Source", true, DataType_ImageU8)
  439. ),
  440. InsSig::create(U"COPY", 1,
  441. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  442. draw_copy(IMAGE_RGBAU8_REF(0), IMAGE_RGBAU8_REF(3), INT_VALUE(1), INT_VALUE(2));
  443. NEXT_INSTRUCTION
  444. },
  445. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  446. ArgSig(U"TargetLeft", true, DataType_FixedPoint),
  447. ArgSig(U"TargetTop", true, DataType_FixedPoint),
  448. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  449. ),
  450. InsSig::create(U"COPY", 1,
  451. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  452. draw_copy(
  453. IMAGE_U8_REF(0),
  454. image_getSubImage(IMAGE_U8_REF(3), IRect(INT_VALUE(4), INT_VALUE(5), INT_VALUE(6), INT_VALUE(7))),
  455. INT_VALUE(1), INT_VALUE(2)
  456. );
  457. NEXT_INSTRUCTION
  458. },
  459. // TODO: Prevent aliasing between IMAGE_U8_REF(0) and IMAGE_U8_REF(3) in compile-time
  460. // This will be added as another lambda running safety checks on suggested inputs
  461. // The result will either accept, pass on to the next overload or abort compilation
  462. // Passing to another overload can be used to fall back on a run-time checked operation
  463. ArgSig(U"Target", false, DataType_ImageU8),
  464. ArgSig(U"TargetLeft", true, DataType_FixedPoint),
  465. ArgSig(U"TargetTop", true, DataType_FixedPoint),
  466. ArgSig(U"Source", true, DataType_ImageU8),
  467. ArgSig(U"SourceLeft", true, DataType_FixedPoint),
  468. ArgSig(U"SourceTop", true, DataType_FixedPoint),
  469. ArgSig(U"SourceWidth", true, DataType_FixedPoint),
  470. ArgSig(U"SourceHeight", true, DataType_FixedPoint)
  471. ),
  472. InsSig::create(U"COPY", 1,
  473. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  474. draw_copy(
  475. IMAGE_RGBAU8_REF(0),
  476. image_getSubImage(IMAGE_RGBAU8_REF(3), IRect(INT_VALUE(4), INT_VALUE(5), INT_VALUE(6), INT_VALUE(7))),
  477. INT_VALUE(1), INT_VALUE(2)
  478. );
  479. NEXT_INSTRUCTION
  480. },
  481. // TODO: Prevent aliasing
  482. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  483. ArgSig(U"TargetLeft", true, DataType_FixedPoint),
  484. ArgSig(U"TargetTop", true, DataType_FixedPoint),
  485. ArgSig(U"Source", true, DataType_ImageRgbaU8),
  486. ArgSig(U"SourceLeft", true, DataType_FixedPoint),
  487. ArgSig(U"SourceTop", true, DataType_FixedPoint),
  488. ArgSig(U"SourceWidth", true, DataType_FixedPoint),
  489. ArgSig(U"SourceHeight", true, DataType_FixedPoint)
  490. ),
  491. InsSig::create(U"GET_RED", 1,
  492. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  493. IMAGE_U8_REF(0) = image_get_red(IMAGE_RGBAU8_REF(1));
  494. NEXT_INSTRUCTION
  495. },
  496. ArgSig(U"Target", false, DataType_ImageU8),
  497. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  498. ),
  499. InsSig::create(U"GET_GREEN", 1,
  500. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  501. IMAGE_U8_REF(0) = image_get_green(IMAGE_RGBAU8_REF(1));
  502. NEXT_INSTRUCTION
  503. },
  504. ArgSig(U"Target", false, DataType_ImageU8),
  505. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  506. ),
  507. InsSig::create(U"GET_BLUE", 1,
  508. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  509. IMAGE_U8_REF(0) = image_get_blue(IMAGE_RGBAU8_REF(1));
  510. NEXT_INSTRUCTION
  511. },
  512. ArgSig(U"Target", false, DataType_ImageU8),
  513. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  514. ),
  515. InsSig::create(U"GET_ALPHA", 1,
  516. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  517. IMAGE_U8_REF(0) = image_get_alpha(IMAGE_RGBAU8_REF(1));
  518. NEXT_INSTRUCTION
  519. },
  520. ArgSig(U"Target", false, DataType_ImageU8),
  521. ArgSig(U"Source", true, DataType_ImageRgbaU8)
  522. ),
  523. InsSig::create(U"PACK_RGBA", 1,
  524. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  525. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4));
  526. NEXT_INSTRUCTION
  527. },
  528. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  529. ArgSig(U"Red", true, DataType_ImageU8),
  530. ArgSig(U"Green", true, DataType_FixedPoint),
  531. ArgSig(U"Blue", true, DataType_FixedPoint),
  532. ArgSig(U"Alpha", true, DataType_FixedPoint)
  533. ),
  534. InsSig::create(U"PACK_RGBA", 1,
  535. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  536. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), IMAGE_U8_REF(2), INT_VALUE(3), INT_VALUE(4));
  537. NEXT_INSTRUCTION
  538. },
  539. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  540. ArgSig(U"Red", true, DataType_FixedPoint),
  541. ArgSig(U"Green", true, DataType_ImageU8),
  542. ArgSig(U"Blue", true, DataType_FixedPoint),
  543. ArgSig(U"Alpha", true, DataType_FixedPoint)
  544. ),
  545. InsSig::create(U"PACK_RGBA", 1,
  546. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  547. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), INT_VALUE(2), IMAGE_U8_REF(3), INT_VALUE(4));
  548. NEXT_INSTRUCTION
  549. },
  550. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  551. ArgSig(U"Red", true, DataType_FixedPoint),
  552. ArgSig(U"Green", true, DataType_FixedPoint),
  553. ArgSig(U"Blue", true, DataType_ImageU8),
  554. ArgSig(U"Alpha", true, DataType_FixedPoint)
  555. ),
  556. InsSig::create(U"PACK_RGBA", 1,
  557. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  558. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), IMAGE_U8_REF(4));
  559. NEXT_INSTRUCTION
  560. },
  561. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  562. ArgSig(U"Red", true, DataType_FixedPoint),
  563. ArgSig(U"Green", true, DataType_FixedPoint),
  564. ArgSig(U"Blue", true, DataType_FixedPoint),
  565. ArgSig(U"Alpha", true, DataType_ImageU8)
  566. ),
  567. InsSig::create(U"PACK_RGBA", 1,
  568. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  569. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), IMAGE_U8_REF(2), INT_VALUE(3), INT_VALUE(4));
  570. NEXT_INSTRUCTION
  571. },
  572. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  573. ArgSig(U"Red", true, DataType_ImageU8),
  574. ArgSig(U"Green", true, DataType_ImageU8),
  575. ArgSig(U"Blue", true, DataType_FixedPoint),
  576. ArgSig(U"Alpha", true, DataType_FixedPoint)
  577. ),
  578. InsSig::create(U"PACK_RGBA", 1,
  579. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  580. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), INT_VALUE(2), IMAGE_U8_REF(3), INT_VALUE(4));
  581. NEXT_INSTRUCTION
  582. },
  583. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  584. ArgSig(U"Red", true, DataType_ImageU8),
  585. ArgSig(U"Green", true, DataType_FixedPoint),
  586. ArgSig(U"Blue", true, DataType_ImageU8),
  587. ArgSig(U"Alpha", true, DataType_FixedPoint)
  588. ),
  589. InsSig::create(U"PACK_RGBA", 1,
  590. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  591. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), INT_VALUE(2), INT_VALUE(3), IMAGE_U8_REF(4));
  592. NEXT_INSTRUCTION
  593. },
  594. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  595. ArgSig(U"Red", true, DataType_ImageU8),
  596. ArgSig(U"Green", true, DataType_FixedPoint),
  597. ArgSig(U"Blue", true, DataType_FixedPoint),
  598. ArgSig(U"Alpha", true, DataType_ImageU8)
  599. ),
  600. InsSig::create(U"PACK_RGBA", 1,
  601. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  602. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), IMAGE_U8_REF(2), IMAGE_U8_REF(3), INT_VALUE(4));
  603. NEXT_INSTRUCTION
  604. },
  605. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  606. ArgSig(U"Red", true, DataType_FixedPoint),
  607. ArgSig(U"Green", true, DataType_ImageU8),
  608. ArgSig(U"Blue", true, DataType_ImageU8),
  609. ArgSig(U"Alpha", true, DataType_FixedPoint)
  610. ),
  611. InsSig::create(U"PACK_RGBA", 1,
  612. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  613. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), IMAGE_U8_REF(2), INT_VALUE(3), IMAGE_U8_REF(4));
  614. NEXT_INSTRUCTION
  615. },
  616. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  617. ArgSig(U"Red", true, DataType_FixedPoint),
  618. ArgSig(U"Green", true, DataType_ImageU8),
  619. ArgSig(U"Blue", true, DataType_FixedPoint),
  620. ArgSig(U"Alpha", true, DataType_ImageU8)
  621. ),
  622. InsSig::create(U"PACK_RGBA", 1,
  623. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  624. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), INT_VALUE(2), IMAGE_U8_REF(3), IMAGE_U8_REF(4));
  625. NEXT_INSTRUCTION
  626. },
  627. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  628. ArgSig(U"Red", true, DataType_FixedPoint),
  629. ArgSig(U"Green", true, DataType_FixedPoint),
  630. ArgSig(U"Blue", true, DataType_ImageU8),
  631. ArgSig(U"Alpha", true, DataType_ImageU8)
  632. ),
  633. InsSig::create(U"PACK_RGBA", 1,
  634. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  635. IMAGE_RGBAU8_REF(0) = image_pack(INT_VALUE(1), IMAGE_U8_REF(2), IMAGE_U8_REF(3), IMAGE_U8_REF(4));
  636. NEXT_INSTRUCTION
  637. },
  638. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  639. ArgSig(U"Red", true, DataType_FixedPoint),
  640. ArgSig(U"Green", true, DataType_ImageU8),
  641. ArgSig(U"Blue", true, DataType_ImageU8),
  642. ArgSig(U"Alpha", true, DataType_ImageU8)
  643. ),
  644. InsSig::create(U"PACK_RGBA", 1,
  645. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  646. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), INT_VALUE(2), IMAGE_U8_REF(3), IMAGE_U8_REF(4));
  647. NEXT_INSTRUCTION
  648. },
  649. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  650. ArgSig(U"Red", true, DataType_ImageU8),
  651. ArgSig(U"Green", true, DataType_FixedPoint),
  652. ArgSig(U"Blue", true, DataType_ImageU8),
  653. ArgSig(U"Alpha", true, DataType_ImageU8)
  654. ),
  655. InsSig::create(U"PACK_RGBA", 1,
  656. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  657. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), IMAGE_U8_REF(2), INT_VALUE(3), IMAGE_U8_REF(4));
  658. NEXT_INSTRUCTION
  659. },
  660. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  661. ArgSig(U"Red", true, DataType_ImageU8),
  662. ArgSig(U"Green", true, DataType_ImageU8),
  663. ArgSig(U"Blue", true, DataType_FixedPoint),
  664. ArgSig(U"Alpha", true, DataType_ImageU8)
  665. ),
  666. InsSig::create(U"PACK_RGBA", 1,
  667. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  668. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), IMAGE_U8_REF(2), IMAGE_U8_REF(3), INT_VALUE(4));
  669. NEXT_INSTRUCTION
  670. },
  671. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  672. ArgSig(U"Red", true, DataType_ImageU8),
  673. ArgSig(U"Green", true, DataType_ImageU8),
  674. ArgSig(U"Blue", true, DataType_ImageU8),
  675. ArgSig(U"Alpha", true, DataType_FixedPoint)
  676. ),
  677. InsSig::create(U"PACK_RGBA", 1,
  678. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  679. IMAGE_RGBAU8_REF(0) = image_pack(IMAGE_U8_REF(1), IMAGE_U8_REF(2), IMAGE_U8_REF(3), IMAGE_U8_REF(4));
  680. NEXT_INSTRUCTION
  681. },
  682. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  683. ArgSig(U"Red", true, DataType_ImageU8),
  684. ArgSig(U"Green", true, DataType_ImageU8),
  685. ArgSig(U"Blue", true, DataType_ImageU8),
  686. ArgSig(U"Alpha", true, DataType_ImageU8)
  687. ),
  688. InsSig::create(U"LINE", 1,
  689. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  690. draw_line(IMAGE_U8_REF(0), INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4), INT_VALUE(5));
  691. NEXT_INSTRUCTION
  692. },
  693. ArgSig(U"Target", false, DataType_ImageU8),
  694. ArgSig(U"X1", true, DataType_FixedPoint),
  695. ArgSig(U"Y1", true, DataType_FixedPoint),
  696. ArgSig(U"X2", true, DataType_FixedPoint),
  697. ArgSig(U"Y2", true, DataType_FixedPoint),
  698. ArgSig(U"Luma", true, DataType_FixedPoint)
  699. ),
  700. InsSig::create(U"LINE", 1,
  701. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  702. draw_line(
  703. IMAGE_RGBAU8_REF(0),
  704. INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4),
  705. ColorRgbaI32(INT_VALUE(5), INT_VALUE(6), INT_VALUE(7), INT_VALUE(8))
  706. );
  707. NEXT_INSTRUCTION
  708. },
  709. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  710. ArgSig(U"X1", true, DataType_FixedPoint),
  711. ArgSig(U"Y1", true, DataType_FixedPoint),
  712. ArgSig(U"X2", true, DataType_FixedPoint),
  713. ArgSig(U"Y2", true, DataType_FixedPoint),
  714. ArgSig(U"Red", true, DataType_FixedPoint),
  715. ArgSig(U"Green", true, DataType_FixedPoint),
  716. ArgSig(U"Blue", true, DataType_FixedPoint),
  717. ArgSig(U"Alpha", true, DataType_FixedPoint)
  718. ),
  719. InsSig::create(U"FADE_LINEAR", 1,
  720. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  721. media_fade_linear(IMAGE_U8_REF(0), SCALAR_VALUE(1), SCALAR_VALUE(2), SCALAR_VALUE(3), SCALAR_VALUE(4), SCALAR_VALUE(5), SCALAR_VALUE(6));
  722. NEXT_INSTRUCTION
  723. },
  724. ArgSig(U"Target", false, DataType_ImageU8),
  725. ArgSig(U"X1", true, DataType_FixedPoint),
  726. ArgSig(U"Y1", true, DataType_FixedPoint),
  727. ArgSig(U"Luma1", true, DataType_FixedPoint), // At x1, y1
  728. ArgSig(U"X2", true, DataType_FixedPoint),
  729. ArgSig(U"Y2", true, DataType_FixedPoint),
  730. ArgSig(U"Luma2", true, DataType_FixedPoint) // At x2, y2
  731. ),
  732. InsSig::create(U"FADE_REGION_LINEAR", 1,
  733. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  734. media_fade_region_linear(IMAGE_U8_REF(0), IRect(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4)), SCALAR_VALUE(5), SCALAR_VALUE(6), SCALAR_VALUE(7), SCALAR_VALUE(8), SCALAR_VALUE(9), SCALAR_VALUE(10));
  735. NEXT_INSTRUCTION
  736. },
  737. ArgSig(U"Target", false, DataType_ImageU8),
  738. ArgSig(U"Left", true, DataType_FixedPoint),
  739. ArgSig(U"Top", true, DataType_FixedPoint),
  740. ArgSig(U"Width", true, DataType_FixedPoint),
  741. ArgSig(U"Height", true, DataType_FixedPoint),
  742. ArgSig(U"X1", true, DataType_FixedPoint), // Relative to Left
  743. ArgSig(U"Y1", true, DataType_FixedPoint), // Relative to Top
  744. ArgSig(U"Luma1", true, DataType_FixedPoint), // At Left + X1, Top + Y1
  745. ArgSig(U"X2", true, DataType_FixedPoint), // Relative to Left
  746. ArgSig(U"Y2", true, DataType_FixedPoint), // Relative to Top
  747. ArgSig(U"Luma2", true, DataType_FixedPoint) // At Left + X2, Top + Y2
  748. ),
  749. //void media_fade_radial(ImageU8& targetImage, FixedPoint centerX, FixedPoint centerY, FixedPoint innerRadius, FixedPoint innerLuma, FixedPoint outerRadius, FixedPoint outerLuma);
  750. InsSig::create(U"FADE_RADIAL", 1,
  751. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  752. media_fade_radial(IMAGE_U8_REF(0), SCALAR_VALUE(1), SCALAR_VALUE(2), SCALAR_VALUE(3), SCALAR_VALUE(4), SCALAR_VALUE(5), SCALAR_VALUE(6));
  753. NEXT_INSTRUCTION
  754. },
  755. ArgSig(U"Target", false, DataType_ImageU8),
  756. ArgSig(U"CenterX", true, DataType_FixedPoint),
  757. ArgSig(U"CenterY", true, DataType_FixedPoint),
  758. ArgSig(U"InnerRadius", true, DataType_FixedPoint),
  759. ArgSig(U"InnerLuma", true, DataType_FixedPoint),
  760. ArgSig(U"OuterRadius", true, DataType_FixedPoint),
  761. ArgSig(U"OuterLuma", true, DataType_FixedPoint)
  762. ),
  763. // void media_fade_region_radial(ImageU8& targetImage, const IRect& viewport, FixedPoint centerX, FixedPoint centerY, FixedPoint innerRadius, FixedPoint innerLuma, FixedPoint outerRadius, FixedPoint outerLuma);
  764. InsSig::create(U"FADE_REGION_RADIAL", 1,
  765. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  766. media_fade_region_radial(IMAGE_U8_REF(0), IRect(INT_VALUE(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4)), SCALAR_VALUE(5), SCALAR_VALUE(6), SCALAR_VALUE(7), SCALAR_VALUE(8), SCALAR_VALUE(9), SCALAR_VALUE(10));
  767. NEXT_INSTRUCTION
  768. },
  769. ArgSig(U"Target", false, DataType_ImageU8),
  770. ArgSig(U"Left", true, DataType_FixedPoint),
  771. ArgSig(U"Top", true, DataType_FixedPoint),
  772. ArgSig(U"Width", true, DataType_FixedPoint),
  773. ArgSig(U"Height", true, DataType_FixedPoint),
  774. ArgSig(U"CenterX", true, DataType_FixedPoint),
  775. ArgSig(U"CenterY", true, DataType_FixedPoint),
  776. ArgSig(U"InnerRadius", true, DataType_FixedPoint),
  777. ArgSig(U"InnerLuma", true, DataType_FixedPoint),
  778. ArgSig(U"OuterRadius", true, DataType_FixedPoint),
  779. ArgSig(U"OuterLuma", true, DataType_FixedPoint)
  780. ),
  781. InsSig::create(U"WRITE_PIXEL", 1,
  782. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  783. image_writePixel(IMAGE_U8_REF(0), INT_VALUE(1), INT_VALUE(2), INT_VALUE(3));
  784. NEXT_INSTRUCTION
  785. },
  786. ArgSig(U"Target", false, DataType_ImageU8),
  787. ArgSig(U"X", true, DataType_FixedPoint),
  788. ArgSig(U"Y", true, DataType_FixedPoint),
  789. ArgSig(U"Luma", true, DataType_FixedPoint)
  790. ),
  791. InsSig::create(U"WRITE_PIXEL", 1,
  792. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  793. image_writePixel(
  794. IMAGE_RGBAU8_REF(0),
  795. INT_VALUE(1), INT_VALUE(2),
  796. ColorRgbaI32(INT_VALUE(3), INT_VALUE(4), INT_VALUE(5), INT_VALUE(6))
  797. );
  798. NEXT_INSTRUCTION
  799. },
  800. ArgSig(U"Target", false, DataType_ImageRgbaU8),
  801. ArgSig(U"X", true, DataType_FixedPoint),
  802. ArgSig(U"Y", true, DataType_FixedPoint),
  803. ArgSig(U"Red", true, DataType_FixedPoint),
  804. ArgSig(U"Green", true, DataType_FixedPoint),
  805. ArgSig(U"Blue", true, DataType_FixedPoint),
  806. ArgSig(U"Alpha", true, DataType_FixedPoint)
  807. ),
  808. InsSig::create(U"READ_PIXEL_BORDER", 1,
  809. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  810. SCALAR_REF(0) = FixedPoint::fromWhole(image_readPixel_border(IMAGE_U8_REF(1), INT_VALUE(2), INT_VALUE(3), INT_VALUE(4)));
  811. NEXT_INSTRUCTION
  812. },
  813. ArgSig(U"LumaOutput", false, DataType_FixedPoint),
  814. ArgSig(U"Source", true, DataType_ImageU8),
  815. ArgSig(U"X", true, DataType_FixedPoint),
  816. ArgSig(U"Y", true, DataType_FixedPoint),
  817. ArgSig(U"LumaBorder", true, DataType_FixedPoint)
  818. ),
  819. InsSig::create(U"READ_PIXEL_BORDER", 4,
  820. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  821. ColorRgbaI32 result = image_readPixel_border(
  822. IMAGE_RGBAU8_REF(4),
  823. INT_VALUE(5), INT_VALUE(6),
  824. ColorRgbaI32(INT_VALUE(7), INT_VALUE(8), INT_VALUE(9), INT_VALUE(10))
  825. );
  826. SCALAR_REF(0) = FixedPoint::fromWhole(result.red);
  827. SCALAR_REF(1) = FixedPoint::fromWhole(result.green);
  828. SCALAR_REF(2) = FixedPoint::fromWhole(result.blue);
  829. SCALAR_REF(3) = FixedPoint::fromWhole(result.alpha);
  830. NEXT_INSTRUCTION
  831. },
  832. ArgSig(U"RedOutput", false, DataType_FixedPoint),
  833. ArgSig(U"GreenOutput", false, DataType_FixedPoint),
  834. ArgSig(U"BlueOutput", false, DataType_FixedPoint),
  835. ArgSig(U"AlphaOutput", false, DataType_FixedPoint),
  836. ArgSig(U"Source", true, DataType_ImageRgbaU8),
  837. ArgSig(U"X", true, DataType_FixedPoint),
  838. ArgSig(U"Y", true, DataType_FixedPoint),
  839. ArgSig(U"RedBorder", true, DataType_FixedPoint),
  840. ArgSig(U"GreenBorder", true, DataType_FixedPoint),
  841. ArgSig(U"BlueBorder", true, DataType_FixedPoint),
  842. ArgSig(U"AlphaBorder", true, DataType_FixedPoint)
  843. ),
  844. InsSig::create(U"READ_PIXEL_CLAMP", 1,
  845. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  846. SCALAR_REF(0) = FixedPoint::fromWhole(image_readPixel_clamp(IMAGE_U8_REF(1), INT_VALUE(2), INT_VALUE(3)));
  847. NEXT_INSTRUCTION
  848. },
  849. ArgSig(U"LumaOutput", false, DataType_FixedPoint),
  850. ArgSig(U"Source", true, DataType_ImageU8),
  851. ArgSig(U"X", true, DataType_FixedPoint),
  852. ArgSig(U"Y", true, DataType_FixedPoint)
  853. ),
  854. InsSig::create(U"READ_PIXEL_CLAMP", 4,
  855. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  856. ColorRgbaI32 result = image_readPixel_clamp(
  857. IMAGE_RGBAU8_REF(4),
  858. INT_VALUE(5), INT_VALUE(6)
  859. );
  860. SCALAR_REF(0) = FixedPoint::fromWhole(result.red);
  861. SCALAR_REF(1) = FixedPoint::fromWhole(result.green);
  862. SCALAR_REF(2) = FixedPoint::fromWhole(result.blue);
  863. SCALAR_REF(3) = FixedPoint::fromWhole(result.alpha);
  864. NEXT_INSTRUCTION
  865. },
  866. ArgSig(U"RedOutput", false, DataType_FixedPoint),
  867. ArgSig(U"GreenOutput", false, DataType_FixedPoint),
  868. ArgSig(U"BlueOutput", false, DataType_FixedPoint),
  869. ArgSig(U"AlphaOutput", false, DataType_FixedPoint),
  870. ArgSig(U"Source", true, DataType_ImageRgbaU8),
  871. ArgSig(U"X", true, DataType_FixedPoint),
  872. ArgSig(U"Y", true, DataType_FixedPoint)
  873. ),
  874. InsSig::create(U"READ_PIXEL_TILE", 1,
  875. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  876. SCALAR_REF(0) = FixedPoint::fromWhole(image_readPixel_tile(IMAGE_U8_REF(1), INT_VALUE(2), INT_VALUE(3)));
  877. NEXT_INSTRUCTION
  878. },
  879. ArgSig(U"LumaOutput", false, DataType_FixedPoint),
  880. ArgSig(U"Source", true, DataType_ImageU8),
  881. ArgSig(U"X", true, DataType_FixedPoint),
  882. ArgSig(U"Y", true, DataType_FixedPoint)
  883. ),
  884. InsSig::create(U"READ_PIXEL_TILE", 4,
  885. [](VirtualMachine& machine, PlanarMemory& memory, const List<VMA>& args) {
  886. ColorRgbaI32 result = image_readPixel_tile(
  887. IMAGE_RGBAU8_REF(4),
  888. INT_VALUE(5), INT_VALUE(6)
  889. );
  890. SCALAR_REF(0) = FixedPoint::fromWhole(result.red);
  891. SCALAR_REF(1) = FixedPoint::fromWhole(result.green);
  892. SCALAR_REF(2) = FixedPoint::fromWhole(result.blue);
  893. SCALAR_REF(3) = FixedPoint::fromWhole(result.alpha);
  894. NEXT_INSTRUCTION
  895. },
  896. ArgSig(U"RedOutput", false, DataType_FixedPoint),
  897. ArgSig(U"GreenOutput", false, DataType_FixedPoint),
  898. ArgSig(U"BlueOutput", false, DataType_FixedPoint),
  899. ArgSig(U"AlphaOutput", false, DataType_FixedPoint),
  900. ArgSig(U"Source", true, DataType_ImageRgbaU8),
  901. ArgSig(U"X", true, DataType_FixedPoint),
  902. ArgSig(U"Y", true, DataType_FixedPoint)
  903. )
  904. };
  905. // API implementation
  906. static void checkMethodIndex(MediaMachine& machine, int methodIndex) {
  907. if (methodIndex < 0 || methodIndex >= machine->methods.length()) {
  908. throwError("Invalid method index ", methodIndex, " of 0..", (machine->methods.length() - 1), ".");
  909. }
  910. }
  911. MediaMachine machine_create(const ReadableString& code) {
  912. std::shared_ptr<PlanarMemory> memory = std::make_shared<MediaMemory>();
  913. static const int mediaMachineInstructionCount = sizeof(mediaMachineInstructions) / sizeof(InsSig);
  914. static const int mediaMachineTypeCount = sizeof(mediaMachineTypes) / sizeof(VMTypeDef);
  915. return MediaMachine(std::make_shared<VirtualMachine>(code, memory, mediaMachineInstructions, mediaMachineInstructionCount, mediaMachineTypes, mediaMachineTypeCount));
  916. }
  917. void machine_executeMethod(MediaMachine& machine, int methodIndex) {
  918. checkMethodIndex(machine, methodIndex);
  919. machine->executeMethod(methodIndex);
  920. }
  921. template <typename T>
  922. static void setInputByIndex(MemoryPlane<T>& stack, int framePointer, Method& method, DataType givenType, int inputIndex, const T& value) {
  923. if (inputIndex < 0 || inputIndex >= method.inputCount) {
  924. throwError("Invalid input index ", inputIndex, " of 0..", (method.inputCount - 1), ".");
  925. }
  926. Variable* variable = &method.locals[inputIndex];
  927. DataType expected = variable->typeDescription->dataType;
  928. if (givenType != expected) {
  929. throwError("Cannot assign ", getMediaTypeName(givenType), " to ", variable->name, " of ", getMediaTypeName(expected), ".");
  930. }
  931. stack.accessByStackIndex(framePointer + variable->typeLocalIndex) = value;
  932. }
  933. template <typename T>
  934. static T& accessOutputByIndex(MemoryPlane<T>& stack, int framePointer, Method& method, DataType wantedType, int outputIndex) {
  935. if (outputIndex < 0 || outputIndex >= method.outputCount) {
  936. throwError("Invalid output index ", outputIndex, " of 0..", (method.outputCount - 1), ".");
  937. }
  938. Variable* variable = &method.locals[method.inputCount + outputIndex];
  939. DataType foundType = variable->typeDescription->dataType;
  940. if (wantedType != foundType) {
  941. throwError("Cannot get ", variable->name, " of ", getMediaTypeName(wantedType), " as ", getMediaTypeName(wantedType), ".");
  942. }
  943. return stack.accessByStackIndex(framePointer + variable->typeLocalIndex);
  944. }
  945. // Set input by argument index
  946. // Indexed arguments are confirmed to be inputs during compilation of the script
  947. void machine_setInputByIndex(MediaMachine& machine, int methodIndex, int inputIndex, int32_t input) {
  948. checkMethodIndex(machine, methodIndex);
  949. setInputByIndex(((MediaMemory*)machine->memory.get())->FixedPointMemory, machine->memory->current.framePointer[DataType_FixedPoint], machine->methods[methodIndex], DataType_FixedPoint, inputIndex, FixedPoint::fromWhole(input));
  950. }
  951. void machine_setInputByIndex(MediaMachine& machine, int methodIndex, int inputIndex, const FixedPoint& input) {
  952. checkMethodIndex(machine, methodIndex);
  953. setInputByIndex(((MediaMemory*)machine->memory.get())->FixedPointMemory, machine->memory->current.framePointer[DataType_FixedPoint], machine->methods[methodIndex], DataType_FixedPoint, inputIndex, input);
  954. }
  955. void machine_setInputByIndex(MediaMachine& machine, int methodIndex, int inputIndex, const AlignedImageU8& input) {
  956. checkMethodIndex(machine, methodIndex);
  957. setInputByIndex(((MediaMemory*)machine->memory.get())->AlignedImageU8Memory, machine->memory->current.framePointer[DataType_ImageU8], machine->methods[methodIndex], DataType_ImageU8, inputIndex, input);
  958. }
  959. void machine_setInputByIndex(MediaMachine& machine, int methodIndex, int inputIndex, const OrderedImageRgbaU8& input) {
  960. checkMethodIndex(machine, methodIndex);
  961. setInputByIndex(((MediaMemory*)machine->memory.get())->OrderedImageRgbaU8Memory, machine->memory->current.framePointer[DataType_ImageRgbaU8], machine->methods[methodIndex], DataType_ImageRgbaU8, inputIndex, input);
  962. }
  963. // Get output by index
  964. FixedPoint machine_getFixedPointOutputByIndex(MediaMachine& machine, int methodIndex, int outputIndex) {
  965. checkMethodIndex(machine, methodIndex);
  966. return accessOutputByIndex<FixedPoint>(((MediaMemory*)machine->memory.get())->FixedPointMemory, machine->memory->current.framePointer[DataType_FixedPoint], machine->methods[methodIndex], DataType_FixedPoint, outputIndex);
  967. }
  968. AlignedImageU8 machine_getImageU8OutputByIndex(MediaMachine& machine, int methodIndex, int outputIndex) {
  969. checkMethodIndex(machine, methodIndex);
  970. return accessOutputByIndex<AlignedImageU8>(((MediaMemory*)machine->memory.get())->AlignedImageU8Memory, machine->memory->current.framePointer[DataType_ImageU8], machine->methods[methodIndex], DataType_ImageU8, outputIndex);
  971. }
  972. OrderedImageRgbaU8 machine_getImageRgbaU8OutputByIndex(MediaMachine& machine, int methodIndex, int outputIndex) {
  973. checkMethodIndex(machine, methodIndex);
  974. return accessOutputByIndex<OrderedImageRgbaU8>(((MediaMemory*)machine->memory.get())->OrderedImageRgbaU8Memory, machine->memory->current.framePointer[DataType_ImageRgbaU8], machine->methods[methodIndex], DataType_ImageRgbaU8, outputIndex);
  975. }
  976. int machine_findMethod(MediaMachine& machine, const ReadableString& methodName) {
  977. return machine->findMethod(methodName);
  978. }
  979. MediaMethod machine_getMethod(MediaMachine& machine, const ReadableString& methodName) {
  980. return MediaMethod(machine, machine_findMethod(machine, methodName));
  981. }
  982. String machine_getMethodName(MediaMachine& machine, int methodIndex) {
  983. checkMethodIndex(machine, methodIndex);
  984. return machine->methods[methodIndex].name;
  985. }
  986. int machine_getInputCount(MediaMachine& machine, int methodIndex) {
  987. checkMethodIndex(machine, methodIndex);
  988. return machine->methods[methodIndex].inputCount;
  989. }
  990. int machine_getOutputCount(MediaMachine& machine, int methodIndex) {
  991. checkMethodIndex(machine, methodIndex);
  992. return machine->methods[methodIndex].outputCount;
  993. }
  994. }