cd_client_images.e 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. deferred class CD_CLIENT_IMAGES
  2. -- There are 2 kinds of client images: RGB and Indexed RGB (or MAP). The RGB
  3. -- image is composed by 3 buffers: red, green and blue (more colors, more
  4. -- memory). The MAP image is composed by 1 buffer of indices for a table and
  5. -- one table of encoded RGB values (less colors, less memory).
  6. --
  7. -- The image buffer is described by its width and height in pixels. The
  8. -- starting point of the buffer is the origin of the image, which is located at
  9. -- its bottom left corner. To retrieve a pixel in the image, use the formula
  10. -- pixel(x,y)=buffer[y*width + x].
  11. --
  12. -- The Put functions may do zoom in or out; zero order interpolation is used to
  13. -- scale the image. It is not possible to specify a part of the image to be
  14. -- drawn.
  15. inherit
  16. CANVAS_DRAW
  17. feature {ANY}
  18. get_image_rgb (x, y, width, height: INTEGER): TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]
  19. -- Returns the red, green and blue components of each pixel in a server
  20. -- image. The RGB components are provided in three arrays. The (i,j)
  21. -- component of these matrices is at the address (j*w+i). As occurs with
  22. -- all primitives from the Canvas Draw library, the pixel (0,0) is at the
  23. -- bottom left corner, and the pixel (w-1,h-1) is that the upper right
  24. -- corner of the image rectangle.
  25. local
  26. p1, p2, p3: POINTER
  27. do
  28. int_canvas_get_image_rgb(cnvs, p1, p2, p3, x, y, width, height)
  29. Result := [convert_to_array(p1, width, height),
  30. convert_to_array(p2, width, height),
  31. convert_to_array(p3, width, height)]
  32. end
  33. get_wd_image_rgb (x, y: REAL_64; width, height: INTEGER): TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]
  34. -- Like "get_image_rgb" but using world coordinates (REAL_64 values).
  35. local
  36. p1, p2, p3: POINTER
  37. do
  38. int_wd_canvas_get_image_rgb(cnvs, p1, p2, p3, x, y, width, height)
  39. Result := [convert_to_array(p1, width, height),
  40. convert_to_array(p2, width, height),
  41. convert_to_array(p3, width, height)]
  42. end
  43. put_image_rect_rgb (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  44. -- Puts, in a specified area of the canvas, an image with its red, green
  45. -- and blue components defined in the three matrices stored in byte
  46. -- arrays. The (i,j) component of these matrices is at the address
  47. -- (j*iw+i). The pixel (0,0) is at the bottom left corner, and the pixel
  48. -- (iw-1,ih-1) is that the upper right corner of the image rectangle.
  49. --
  50. -- Parameters w and h refer to the target rectangle of the canvas, so
  51. -- that it is possible to reduce or expand the image drawn. If w and h
  52. -- are 0, the size of the image is assumed (iw and ih).
  53. --
  54. -- It also allows specifying a rectangle inside the image to be drawn, if
  55. -- xmin, xmax, ymin and ymax are 0 then the whole image is assumed.
  56. --
  57. -- If the driver has bpp <=8 or only 256 colors or less, then the image
  58. -- is converted to 256 optimal colors using the function "rgb_to_map" and
  59. -- is drawn using "put_image_rect_map".
  60. do
  61. int_canvas_put_image_rgb(cnvs, image_width, image_height,
  62. convert_to_character_array(colors.item_1, image_width, image_height),
  63. convert_to_character_array(colors.item_2, image_width, image_height),
  64. convert_to_character_array(colors.item_3, image_width, image_height),
  65. x, y, w, h, xmin, xmax, ymin, ymax)
  66. end
  67. put_image_rect_rgb_real (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  68. -- Like "put_image_rect_rgb" but using REAL_64 values.
  69. do
  70. int_canvas_c_double_put_image_rgb(cnvs, image_width, image_height,
  71. convert_to_character_array(colors.item_1, image_width, image_height),
  72. convert_to_character_array(colors.item_2, image_width, image_height),
  73. convert_to_character_array(colors.item_3, image_width, image_height),
  74. x, y, w, h, xmin, xmax, ymin, ymax)
  75. end
  76. put_wd_image_rect_rgb (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  77. -- Like "put_image_rect_rgb" but using world coordinates (REAL_64 values).
  78. do
  79. int_wd_canvas_put_image_rgb(cnvs, image_width, image_height,
  80. convert_to_character_array(colors.item_1, image_width, image_height),
  81. convert_to_character_array(colors.item_2, image_width, image_height),
  82. convert_to_character_array(colors.item_3, image_width, image_height),
  83. x, y, w, h, xmin, xmax, ymin, ymax)
  84. end
  85. put_image_rect_rgba (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  86. -- The same as function "put_image_rect_rgb", except for the fact that it
  87. -- is possible to specify an alpha channel. The resulting color is the
  88. -- image color weighted by the alpha value, using the formula
  89. -- result=(source * alpha + destiny * (255 - alpha))/255. This means
  90. -- that, if alpha is 0, the resulting color is the target color
  91. -- (completely transparent), and, if alpha is 255, the resulting color is
  92. -- the original image color (completely opaque).
  93. --
  94. -- If this function is not defined for a given driver or if alpha is
  95. -- Void, then the function "put_image_rect_rgb" is used, as long as it is
  96. -- defined.
  97. do
  98. int_canvas_put_image_rgba(cnvs, image_width, image_height,
  99. convert_to_character_array(colors.item_1, image_width, image_height),
  100. convert_to_character_array(colors.item_2, image_width, image_height),
  101. convert_to_character_array(colors.item_3, image_width, image_height),
  102. convert_to_character_array(colors.item_4, image_width, image_height),
  103. x, y, w, h, xmin, xmax, ymin, ymax)
  104. end
  105. put_image_rect_rgba_real (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  106. -- Like "put_image_rect_rgb" but using REAL_64 values.
  107. do
  108. int_canvas_c_double_put_image_rgba(cnvs, image_width, image_height,
  109. convert_to_character_array(colors.item_1, image_width, image_height),
  110. convert_to_character_array(colors.item_2, image_width, image_height),
  111. convert_to_character_array(colors.item_3, image_width, image_height),
  112. convert_to_character_array(colors.item_4, image_width, image_height),
  113. x, y, w, h, xmin, xmax, ymin, ymax)
  114. end
  115. put_wd_image_rect_rgba (image_width, image_height: INTEGER; colors: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  116. -- Like "put_image_rect_rgb" but using world coordinates (REAL_64 values).
  117. do
  118. int_wd_canvas_put_image_rgba(cnvs, image_width, image_height,
  119. convert_to_character_array(colors.item_1, image_width, image_height),
  120. convert_to_character_array(colors.item_2, image_width, image_height),
  121. convert_to_character_array(colors.item_3, image_width, image_height),
  122. convert_to_character_array(colors.item_4, image_width, image_height),
  123. x, y, w, h, xmin, xmax, ymin, ymax)
  124. end
  125. put_image_rect_map (image_width, image_height: INTEGER; index: ARRAY[INTEGER_8]; colors: ARRAY[INTEGER]; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  126. -- The same as function "put_image_rect_rgb", except for the fact that
  127. -- the colors are provided by means of an index matrix (map). The color
  128. -- corresponding to a given index is given in colors[index]. The map is
  129. -- also a matrix stored as a byte vector. If the color vector is Void,
  130. -- then a vector with 256 gray tones is assumed.
  131. do
  132. int_canvas_put_image_map(cnvs, image_width, image_height,
  133. convert_to_character_array(index, image_width, image_height),
  134. convert_to_integer_array(colors, image_width, image_height),
  135. x, y, w, h, xmin, xmax, ymin, ymax)
  136. end
  137. put_image_rect_map_real (image_width, image_height: INTEGER; index: ARRAY[INTEGER_8]; colors: ARRAY[INTEGER]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  138. -- Like "put_image_rect_map" but using REAL_64 values.
  139. do
  140. int_canvas_c_double_put_image_map(cnvs, image_width, image_height,
  141. convert_to_character_array(index, image_width, image_height),
  142. convert_to_integer_array(colors, image_width, image_height),
  143. x, y, w, h, xmin, xmax, ymin, ymax)
  144. end
  145. put_wd_image_rect_map (image_width, image_height: INTEGER; index: ARRAY[INTEGER_8]; colors: ARRAY[INTEGER]; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  146. -- Like "put_image_rect_map" but using world coordinates (REAL_64 values).
  147. do
  148. int_wd_canvas_put_image_map(cnvs, image_width, image_height,
  149. convert_to_character_array(index, image_width, image_height),
  150. convert_to_integer_array(colors, image_width, image_height),
  151. x, y, w, h, xmin, xmax, ymin, ymax)
  152. end
  153. -- Skeep for the moment the imimage features. Instead add
  154. -- IUP_IMAGE features.
  155. get_iup_image (x, y, width, height: INTEGER): IUP_IMAGE
  156. -- The same as the "get_image_rgb" functions except for the fact that use
  157. -- an IUP_IMAGE object.
  158. local
  159. imimg, iupimg: POINTER
  160. image: IUP_IMAGE
  161. do
  162. imimg := int_im_image_create (width, height, 0, 0)
  163. int_canvas_get_im_image(cnvs, imimg, x, y)
  164. iupimg := int_iup_image_from_im_image(imimg)
  165. create image.with_internal(iupimg)
  166. int_im_image_destroy(iupimg)
  167. Result := image
  168. end
  169. get_wd_iup_image (x, y: REAL_64; width, height: INTEGER): IUP_IMAGE
  170. -- The same as "get_iup_image" but with World Coordinates.
  171. local
  172. imimg, iupimg: POINTER
  173. image: IUP_IMAGE
  174. do
  175. imimg := int_im_image_create (width, height, 0, 0)
  176. int_wd_canvas_get_im_image(cnvs, imimg, x, y)
  177. iupimg := int_iup_image_from_im_image(imimg)
  178. create image.with_internal(iupimg)
  179. int_im_image_destroy(iupimg)
  180. Result := image
  181. end
  182. put_iup_image (image: IUP_IMAGE; x, y: INTEGER)
  183. -- The same as the above functions except for the fact that use an
  184. -- IUP_IMAGE object. Image must be a displayable image and it can has an
  185. -- alpha channel.
  186. local
  187. p, img: POINTER
  188. do
  189. p := image.get_wid.deep_twin
  190. img := int_get_native_handle_image(p)
  191. int_canvas_put_im_image(cnvs, img, x, y,
  192. image.get_width,
  193. image.get_height)
  194. end
  195. put_iup_image_real (image: IUP_IMAGE; x, y: REAL_64)
  196. -- Like "put_iup_image" but using REAL_64 values.
  197. local
  198. p, img: POINTER
  199. do
  200. p := image.get_wid.deep_twin
  201. img := int_get_native_handle_image(p)
  202. int_canvas_c_double_put_im_image(cnvs, img, x, y,
  203. image.get_width.to_real_64,
  204. image.get_height.to_real_64)
  205. end
  206. put_wd_iup_image (image: IUP_IMAGE; x, y: REAL_64)
  207. -- Like "put_iup_image" but using World Coordinates.
  208. local
  209. p, img: POINTER
  210. do
  211. p := image.get_wid.deep_twin
  212. img := int_get_native_handle_image(p)
  213. int_wd_canvas_put_im_image(cnvs, img, x, y,
  214. image.get_width.to_real_64,
  215. image.get_height.to_real_64)
  216. end
  217. rgb_to_map (image_width, image_height: INTEGER; rgb_arrays: TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8], ARRAY[INTEGER_8]]; palette_size: INTEGER): TUPLE[ARRAY[INTEGER_8], ARRAY[INTEGER_8]]
  218. -- Converts an RGB image into an image with 256 indexed colors. The
  219. -- resulting image must have the same size (width x height) as the RGB
  220. -- image.
  221. local
  222. index, colors: POINTER
  223. do
  224. int_rgb_to_map(image_width, image_height, rgb_arrays.item_1.to_external, rgb_arrays.item_2.to_external, rgb_arrays.item_3.to_external, index, palette_size, colors)
  225. Result := [convert_to_array(index, image_width, image_height),
  226. convert_to_array(colors, 1.to_integer_32, palette_size)]
  227. end
  228. feature {}
  229. -- Converts
  230. convert_to_array (p: POINTER; w, h: INTEGER): ARRAY[INTEGER_8]
  231. local
  232. i, size: INTEGER
  233. m: NATIVE_ARRAY[CHARACTER]
  234. a: ARRAY[INTEGER_8]
  235. do
  236. if p.is_not_null then
  237. size := w*h - 1
  238. m := m.calloc(size)
  239. m := m.from_pointer(p)
  240. from
  241. i := 0
  242. until
  243. i = size
  244. loop
  245. a.put(m.item(i).to_integer_8, i)
  246. i := i + 1
  247. end
  248. Result := a
  249. end
  250. end
  251. convert_to_character_array (p: ARRAY[INTEGER_8]; w, h: INTEGER): POINTER
  252. local
  253. i, size: INTEGER
  254. m: NATIVE_ARRAY[CHARACTER]
  255. do
  256. if p /= Void then
  257. size := w*h - 1
  258. m := m.calloc(size)
  259. from
  260. i := 0
  261. until
  262. i = size
  263. loop
  264. m.put(p.item(i).to_character, i)
  265. i := i + 1
  266. end
  267. Result := m.to_external
  268. end
  269. end
  270. convert_to_integer_array (p: ARRAY[INTEGER]; w, h: INTEGER): POINTER
  271. local
  272. i, size: INTEGER
  273. m: NATIVE_ARRAY[INTEGER]
  274. do
  275. if p /= Void then
  276. size := w*h - 1
  277. m := m.calloc(size)
  278. from
  279. i := 0
  280. until
  281. i = size
  282. loop
  283. m.put(p.item(i), i)
  284. i := i + 1
  285. end
  286. Result := m.to_external
  287. end
  288. end
  289. -- Internals
  290. int_canvas_get_image_rgb(wgt, r, g, b: POINTER; x, y, iw, ih: INTEGER)
  291. external "plug_in"
  292. alias "{
  293. location: "${sys}/plugins"
  294. module_name: "iup"
  295. feature_name: "cdCanvasGetImageRGB"
  296. }"
  297. end
  298. int_wd_canvas_get_image_rgb(wgt, r, g, b: POINTER; x, y: REAL_64; iw, ih: INTEGER)
  299. external "plug_in"
  300. alias "{
  301. location: "${sys}/plugins"
  302. module_name: "iup"
  303. feature_name: "wdCanvasGetImageRGB"
  304. }"
  305. end
  306. int_canvas_put_image_rgb(wgt: POINTER; iw, ih: INTEGER; r, g, b: POINTER; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  307. external "plug_in"
  308. alias "{
  309. location: "${sys}/plugins"
  310. module_name: "iup"
  311. feature_name: "cdCanvasPutImageRectRGB"
  312. }"
  313. end
  314. int_canvas_c_double_put_image_rgb(wgt: POINTER; iw, ih: INTEGER; r, g, b: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  315. external "plug_in"
  316. alias "{
  317. location: "${sys}/plugins"
  318. module_name: "iup"
  319. feature_name: "cdfCanvasPutImageRectRGB"
  320. }"
  321. end
  322. int_wd_canvas_put_image_rgb(wgt: POINTER; iw, ih: INTEGER; r, g, b: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  323. external "plug_in"
  324. alias "{
  325. location: "${sys}/plugins"
  326. module_name: "iup"
  327. feature_name: "wdCanvasPutImageRectRGB"
  328. }"
  329. end
  330. int_canvas_put_image_rgba(wgt: POINTER; iw, ih: INTEGER; r, g, b, a: POINTER; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  331. external "plug_in"
  332. alias "{
  333. location: "${sys}/plugins"
  334. module_name: "iup"
  335. feature_name: "cdCanvasPutImageRectRGBA"
  336. }"
  337. end
  338. int_canvas_c_double_put_image_rgba(wgt: POINTER; iw, ih: INTEGER; r, g, b, a: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  339. external "plug_in"
  340. alias "{
  341. location: "${sys}/plugins"
  342. module_name: "iup"
  343. feature_name: "cdfCanvasPutImageRectRGBA"
  344. }"
  345. end
  346. int_wd_canvas_put_image_rgba(wgt: POINTER; iw, ih: INTEGER; r, g, b, a: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  347. external "plug_in"
  348. alias "{
  349. location: "${sys}/plugins"
  350. module_name: "iup"
  351. feature_name: "wdCanvasPutImageRectRGBA"
  352. }"
  353. end
  354. int_canvas_put_image_map(wgt: POINTER; iw, ih: INTEGER; i, c: POINTER; x, y, w, h, xmin, xmax, ymin, ymax: INTEGER)
  355. external "plug_in"
  356. alias "{
  357. location: "${sys}/plugins"
  358. module_name: "iup"
  359. feature_name: "cdCanvasPutImageRectMap"
  360. }"
  361. end
  362. int_canvas_c_double_put_image_map(wgt: POINTER; iw, ih: INTEGER; i, c: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  363. external "plug_in"
  364. alias "{
  365. location: "${sys}/plugins"
  366. module_name: "iup"
  367. feature_name: "cdfCanvasPutImageRectMap"
  368. }"
  369. end
  370. int_wd_canvas_put_image_map(wgt: POINTER; iw, ih: INTEGER; i, c: POINTER; x, y, w, h: REAL_64; xmin, xmax, ymin, ymax: INTEGER)
  371. external "plug_in"
  372. alias "{
  373. location: "${sys}/plugins"
  374. module_name: "iup"
  375. feature_name: "wdCanvasPutImageRectMap"
  376. }"
  377. end
  378. int_canvas_get_im_image(wgt, img: POINTER; x, y: INTEGER)
  379. external "plug_in"
  380. alias "{
  381. location: "${sys}/plugins"
  382. module_name: "iup"
  383. feature_name: "cdCanvasGetImImage"
  384. }"
  385. end
  386. int_wd_canvas_get_im_image(wgt, img: POINTER; x, y: REAL_64)
  387. external "plug_in"
  388. alias "{
  389. location: "${sys}/plugins"
  390. module_name: "iup"
  391. feature_name: "wdCanvasGetImImage"
  392. }"
  393. end
  394. int_canvas_put_im_image(wgt, img: POINTER; x, y, w, h: INTEGER)
  395. external "plug_in"
  396. alias "{
  397. location: "${sys}/plugins"
  398. module_name: "iup"
  399. feature_name: "cdCanvasPutImImage"
  400. }"
  401. end
  402. int_canvas_c_double_put_im_image(wgt, img: POINTER; x, y, w, h: REAL_64)
  403. external "plug_in"
  404. alias "{
  405. location: "${sys}/plugins"
  406. module_name: "iup"
  407. feature_name: "cdfCanvasPutImImage"
  408. }"
  409. end
  410. int_wd_canvas_put_im_image(wgt, img: POINTER; x, y, w, h: REAL_64)
  411. external "plug_in"
  412. alias "{
  413. location: "${sys}/plugins"
  414. module_name: "iup"
  415. feature_name: "wdCanvasPutImImage"
  416. }"
  417. end
  418. int_rgb_to_map(iw, ih: INTEGER; r, g, b, i: POINTER; ps: INTEGER; cl: POINTER)
  419. external "plug_in"
  420. alias "{
  421. location: "${sys}/plugins"
  422. module_name: "iup"
  423. feature_name: "cdRGB2Map"
  424. }"
  425. end
  426. int_get_native_handle_image(wgt: POINTER): POINTER
  427. external "plug_in"
  428. alias "{
  429. location: "${sys}/plugins"
  430. module_name: "iup"
  431. feature_name: "IupGetNativeHandleImage"
  432. }"
  433. end
  434. int_iup_image_from_im_image(wgt: POINTER): POINTER
  435. external "plug_in"
  436. alias "{
  437. location: "${sys}/plugins"
  438. module_name: "iup"
  439. feature_name: "IupImageFromImImage"
  440. }"
  441. end
  442. -- These features maybe should be removed in the future.
  443. int_im_image_create(w, h, cs, dt: INTEGER): POINTER
  444. external "plug_in"
  445. alias "{
  446. location: "${sys}/plugins"
  447. module_name: "iup"
  448. feature_name: "imImageCreate"
  449. }"
  450. end
  451. int_im_image_destroy(wgt: POINTER)
  452. external "plug_in"
  453. alias "{
  454. location: "${sys}/plugins"
  455. module_name: "iup"
  456. feature_name: "imImageDestroy"
  457. }"
  458. end
  459. end
  460. -- The MIT License (MIT)
  461. -- Copyright (c) 2017 by German A. Arias
  462. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  463. -- of this software and associated documentation files (the "Software"), to deal
  464. -- in the Software without restriction, including without limitation the rights
  465. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  466. -- copies of the Software, and to permit persons to whom the Software is
  467. -- furnished to do so, subject to the following conditions:
  468. --
  469. -- The above copyright notice and this permission notice shall be included in
  470. -- all copies or substantial portions of the Software.
  471. --
  472. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  473. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  474. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  475. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  476. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  477. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  478. -- SOFTWARE.