├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── doc
├── Makefile
├── colony.css
├── enums.adoc
├── index.adoc
├── index.html
├── load.adoc
├── perlin.adoc
├── powered-by-lua.gif
├── preface.adoc
└── write.adoc
├── examples
├── hello.lua
├── sunflowers.jpg
└── version.lua
├── moonimage
└── README
├── src
├── Makefile
├── _make
├── compat-5.3.c
├── compat-5.3.h
├── include
│ ├── stb_image.h
│ ├── stb_image_write.h
│ └── stb_perlin.h
├── internal.h
├── load.c
├── main.c
├── moonimage.h
├── perlin.c
├── utils.c
└── write.c
└── thirdparty
├── asciidoctor-styles-license
├── lua-compat-5.3-license
├── powered-by-lua-license
└── stb-license
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | *.so
3 | *.dll
4 | *.o
5 | *.swp
6 | *.symbols
7 | core.*
8 | examples/output*.*
9 | local/
10 | src/DIFF
11 | src/TODO
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Stefano Trettel
4 |
5 | Software repository: MoonImage, https://github.com/stetre/moonimage
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
25 |
26 | (See also the THIRD-PARTY LICENSES contained in the thirdparty/ directory
27 | of the Software repository.)
28 |
29 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | default: build
3 |
4 | build install uninstall where:
5 | @cd src; $(MAKE) $@
6 |
7 | clean :
8 | @cd src; $(MAKE) $@
9 | @cd doc; $(MAKE) $@
10 |
11 | docs:
12 | @cd doc; $(MAKE)
13 |
14 | cleanall: clean
15 |
16 | backup: clean
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## MoonImage: Image Loading for Lua
2 |
3 | MoonImage is a Lua image loading library based on Sean Barrett's
4 | [STB libraries](https://github.com/nothings/stb).
5 |
6 | It runs on GNU/Linux and on Windows (MSYS2/MinGW) and requires
7 | [Lua](http://www.lua.org/) (>=5.3).
8 |
9 | _Author:_ _[Stefano Trettel](https://www.linkedin.com/in/stetre)_
10 |
11 | [](http://www.lua.org/)
12 |
13 | #### License
14 |
15 | MIT/X11 license (same as Lua). See [LICENSE](./LICENSE).
16 |
17 | #### Documentation
18 |
19 | See the [Reference Manual](https://stetre.github.io/moonimage/doc/index.html).
20 |
21 | #### Getting and installing
22 |
23 | Setup the build environment as described [here](https://github.com/stetre/moonlibs), then:
24 |
25 | ```sh
26 | $ git clone https://github.com/stetre/moonimage
27 | $ cd moonimage
28 | moonimage$ make
29 | moonimage$ sudo make install
30 | ```
31 |
32 | #### Example
33 |
34 | The example below loads an image from a JPG file and writes it to a BMP file.
35 |
36 | Other examples can be found in the **examples/** directory contained in the release package.
37 |
38 | ```lua
39 | -- MoonImage example: hello.lua
40 | mi = require('moonimage')
41 |
42 | -- Load an image from a jpg file:
43 | data, w, h, channels = mi.load("sunflowers.jpg", 'rgba')
44 |
45 | -- Write it to a bmp file:
46 | mi.write_bmp("output.bmp", w, h, channels, data)
47 | ```
48 |
49 | The script can be executed at the shell prompt with the standard Lua interpreter:
50 |
51 | ```shell
52 | $ lua hello.lua
53 | ```
54 |
55 | #### See also
56 |
57 | * [MoonLibs - Graphics and Audio Lua Libraries](https://github.com/stetre/moonlibs).
58 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | TgtAdoc := index
2 | TgtPdf := MoonImage-RefMan
3 |
4 | Stylesdir = ./
5 | Stylesheet = colony.css
6 | Style = -a stylesheet=$(Stylesheet) -a stylesdir=$(Stylesdir)
7 | Style =
8 |
9 | ifdef TgtAdoc
10 | # one file only
11 | Src = $(TgtAdoc).adoc
12 | else
13 | # all .adoc files
14 | Src := $(wildcard *.adoc)
15 | endif
16 |
17 | Xml := $(Src:.adoc=.xml)
18 | Html := $(Src:.adoc=.html)
19 | Pdf := $(Src:.adoc=.pdf)
20 |
21 | default: html
22 |
23 | check:
24 |
25 | clean:
26 | @-rm -f *~
27 | @-rm -f *.pdf
28 | @-rm -f *.pdfmarks
29 | @-rm -f *.xml
30 | @-rm -f *.html
31 | @-rm -f *.epub
32 | @-rm -f *.fo
33 | @-rm -f *.log
34 |
35 | install:
36 |
37 | html: clean
38 | @asciidoctor $(Style) $(Src)
39 |
40 | preview: html
41 | @google-chrome $(Html)
42 |
43 | ifdef TgtAdoc
44 | # one file only
45 | pdf: clean
46 | @asciidoctor-pdf $(TgtAdoc).adoc -o $(TgtPdf).pdf
47 | else
48 | # all .adoc files
49 | pdf: clean
50 | @asciidoctor-pdf -a pdf-style=asciidoctor $(TgtAdoc).adoc
51 | endif
52 |
53 | docs: html pdf
54 |
--------------------------------------------------------------------------------
/doc/colony.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v2.1.2 | MIT License | git.io/normalize */
2 | /* ========================================================================== HTML5 display definitions ========================================================================== */
3 | /** Correct `block` display not defined in IE 8/9. */
4 | article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
5 |
6 | /** Correct `inline-block` display not defined in IE 8/9. */
7 | audio, canvas, video { display: inline-block; }
8 |
9 | /** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
10 | audio:not([controls]) { display: none; height: 0; }
11 |
12 | /** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */
13 | [hidden], template { display: none; }
14 |
15 | script { display: none !important; }
16 |
17 | /* ========================================================================== Base ========================================================================== */
18 | /** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
19 | html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
20 |
21 | /** Remove default margin. */
22 | body { margin: 0; }
23 |
24 | /* ========================================================================== Links ========================================================================== */
25 | /** Remove the gray background color from active links in IE 10. */
26 | a { background: transparent; }
27 |
28 | /** Address `outline` inconsistency between Chrome and other browsers. */
29 | a:focus { outline: thin dotted; }
30 |
31 | /** Improve readability when focused and also mouse hovered in all browsers. */
32 | a:active, a:hover { outline: 0; }
33 |
34 | /* ========================================================================== Typography ========================================================================== */
35 | /** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */
36 | h1 { font-size: 2em; margin: 0.67em 0; }
37 |
38 | /** Address styling not present in IE 8/9, Safari 5, and Chrome. */
39 | abbr[title] { border-bottom: 1px dotted; }
40 |
41 | /** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */
42 | b, strong { font-weight: bold; }
43 |
44 | /** Address styling not present in Safari 5 and Chrome. */
45 | dfn { font-style: italic; }
46 |
47 | /** Address differences between Firefox and other browsers. */
48 | hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
49 |
50 | /** Address styling not present in IE 8/9. */
51 | mark { background: #ff0; color: #000; }
52 |
53 | /** Correct font family set oddly in Safari 5 and Chrome. */
54 | code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
55 |
56 | /** Improve readability of pre-formatted text in all browsers. */
57 | pre { white-space: pre-wrap; }
58 |
59 | /** Set consistent quote types. */
60 | q { quotes: "\201C" "\201D" "\2018" "\2019"; }
61 |
62 | /** Address inconsistent and variable font size in all browsers. */
63 | small { font-size: 80%; }
64 |
65 | /** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
66 | sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
67 |
68 | sup { top: -0.5em; }
69 |
70 | sub { bottom: -0.25em; }
71 |
72 | /* ========================================================================== Embedded content ========================================================================== */
73 | /** Remove border when inside `a` element in IE 8/9. */
74 | img { border: 0; }
75 |
76 | /** Correct overflow displayed oddly in IE 9. */
77 | svg:not(:root) { overflow: hidden; }
78 |
79 | /* ========================================================================== Figures ========================================================================== */
80 | /** Address margin not present in IE 8/9 and Safari 5. */
81 | figure { margin: 0; }
82 |
83 | /* ========================================================================== Forms ========================================================================== */
84 | /** Define consistent border, margin, and padding. */
85 | fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
86 |
87 | /** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
88 | legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
89 |
90 | /** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */
91 | button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }
92 |
93 | /** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
94 | button, input { line-height: normal; }
95 |
96 | /** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */
97 | button, select { text-transform: none; }
98 |
99 | /** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
100 | button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
101 |
102 | /** Re-set default cursor for disabled elements. */
103 | button[disabled], html input[disabled] { cursor: default; }
104 |
105 | /** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */
106 | input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
107 |
108 | /** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
109 | input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }
110 |
111 | /** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
112 | input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
113 |
114 | /** Remove inner padding and border in Firefox 4+. */
115 | button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
116 |
117 | /** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */
118 | textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }
119 |
120 | /* ========================================================================== Tables ========================================================================== */
121 | /** Remove most spacing between table cells. */
122 | table { border-collapse: collapse; border-spacing: 0; }
123 |
124 | meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; }
125 |
126 | meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; }
127 |
128 | meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; }
129 |
130 | *, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
131 |
132 | html, body { font-size: 100%; }
133 |
134 | body { background: white; color: #222222; padding: 0; margin: 0; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; }
135 |
136 | a:hover { cursor: pointer; }
137 |
138 | img, object, embed { max-width: 100%; height: auto; }
139 |
140 | object, embed { height: 100%; }
141 |
142 | img { -ms-interpolation-mode: bicubic; }
143 |
144 | #map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
145 |
146 | .left { float: left !important; }
147 |
148 | .right { float: right !important; }
149 |
150 | .text-left { text-align: left !important; }
151 |
152 | .text-right { text-align: right !important; }
153 |
154 | .text-center { text-align: center !important; }
155 |
156 | .text-justify { text-align: justify !important; }
157 |
158 | .hide { display: none; }
159 |
160 | .antialiased, body { -webkit-font-smoothing: antialiased; }
161 |
162 | img { display: inline-block; vertical-align: middle; }
163 |
164 | textarea { height: auto; min-height: 50px; }
165 |
166 | select { width: 100%; }
167 |
168 | p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; }
169 |
170 | .subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #003b6b; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
171 |
172 | /* Typography resets */
173 | div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }
174 |
175 | /* Default Link Styles */
176 | a { color: #00579e; text-decoration: none; line-height: inherit; }
177 | a:hover, a:focus { color: #333333; }
178 | a img { border: none; }
179 |
180 | /* Default paragraph styles */
181 | p { font-family: Arial, sans-serif; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; text-rendering: optimizeLegibility; }
182 | p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }
183 |
184 | /* Default header styles */
185 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: Arial, sans-serif; font-weight: normal; font-style: normal; color: #7b2d00; text-rendering: optimizeLegibility; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.2125em; }
186 | h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #ff6b15; line-height: 0; }
187 |
188 | h1 { font-size: 2.125em; }
189 |
190 | h2 { font-size: 1.6875em; }
191 |
192 | h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }
193 |
194 | h4 { font-size: 1.125em; }
195 |
196 | h5 { font-size: 1.125em; }
197 |
198 | h6 { font-size: 1em; }
199 |
200 | hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }
201 |
202 | /* Helpful Typography Defaults */
203 | em, i { font-style: italic; line-height: inherit; }
204 |
205 | strong, b { font-weight: bold; line-height: inherit; }
206 |
207 | small { font-size: 60%; line-height: inherit; }
208 |
209 | code { font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: bold; color: #003426; }
210 |
211 | /* Lists */
212 | ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; list-style-position: outside; font-family: Arial, sans-serif; }
213 |
214 | ul, ol { margin-left: 1.5em; }
215 | ul.no-bullet, ol.no-bullet { margin-left: 1.5em; }
216 |
217 | /* Unordered Lists */
218 | ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }
219 | ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }
220 | ul.square { list-style-type: square; }
221 | ul.circle { list-style-type: circle; }
222 | ul.disc { list-style-type: disc; }
223 | ul.no-bullet { list-style: none; }
224 |
225 | /* Ordered Lists */
226 | ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
227 |
228 | /* Definition Lists */
229 | dl dt { margin-bottom: 0.3em; font-weight: bold; }
230 | dl dd { margin-bottom: 0.75em; }
231 |
232 | /* Abbreviations */
233 | abbr, acronym { text-transform: uppercase; font-size: 90%; color: black; border-bottom: 1px dotted #dddddd; cursor: help; }
234 |
235 | abbr { text-transform: none; }
236 |
237 | /* Blockquotes */
238 | blockquote { margin: 0 0 0.75em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; }
239 | blockquote cite { display: block; font-size: 0.8125em; color: #e15200; }
240 | blockquote cite:before { content: "\2014 \0020"; }
241 | blockquote cite a, blockquote cite a:visited { color: #e15200; }
242 |
243 | blockquote, blockquote p { line-height: 1.6; color: #333333; }
244 |
245 | /* Microformats */
246 | .vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; }
247 | .vcard li { margin: 0; display: block; }
248 | .vcard .fn { font-weight: bold; font-size: 0.9375em; }
249 |
250 | .vevent .summary { font-weight: bold; }
251 | .vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }
252 |
253 | @media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }
254 | h1 { font-size: 2.75em; }
255 | h2 { font-size: 2.3125em; }
256 | h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
257 | h4 { font-size: 1.4375em; } }
258 | /* Tables */
259 | table { background: white; margin-bottom: 1.25em; border: solid 1px #d8d8ce; }
260 | table thead, table tfoot { background: -webkit-linear-gradient(top, #add386, #90b66a); font-weight: bold; }
261 | table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: white; text-align: left; }
262 | table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #6d6e71; }
263 | table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #edf2f2; }
264 | table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.4; }
265 |
266 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }
267 |
268 | a:hover, a:focus { text-decoration: underline; }
269 |
270 | .clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
271 | .clearfix:after, .float-group:after { clear: both; }
272 |
273 | *:not(pre) > code { font-size: inherit; font-style: normal !important; letter-spacing: 0; padding: 3px 2px 1px 2px; background-color: #eeeeee; border: 1px solid #dddddd; -webkit-border-radius: 0; border-radius: 0; line-height: inherit; }
274 |
275 | pre, pre > code { line-height: 1.6; color: black; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; }
276 |
277 | .keyseq { color: #333333; }
278 |
279 | kbd { display: inline-block; color: black; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
280 |
281 | .keyseq kbd:first-child { margin-left: 0; }
282 |
283 | .keyseq kbd:last-child { margin-right: 0; }
284 |
285 | .menuseq, .menu { color: black; }
286 |
287 | b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
288 |
289 | b.button:before { content: "["; padding: 0 3px 0 2px; }
290 |
291 | b.button:after { content: "]"; padding: 0 2px 0 3px; }
292 |
293 | #header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 1.5em; padding-right: 1.5em; }
294 | #header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
295 | #header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
296 |
297 | #content { margin-top: 1.25em; }
298 |
299 | #content:before { content: none; }
300 |
301 | #header > h1:first-child { color: #7b2d00; margin-top: 2.25rem; margin-bottom: 0; }
302 | #header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #dddddd; }
303 | #header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #dddddd; padding-bottom: 8px; }
304 | #header .details { border-bottom: 1px solid #dddddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #e15200; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; }
305 | #header .details span:first-child { margin-left: -0.125em; }
306 | #header .details span.email a { color: #333333; }
307 | #header .details br { display: none; }
308 | #header .details br + span:before { content: "\00a0\2013\00a0"; }
309 | #header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #333333; }
310 | #header .details br + span#revremark:before { content: "\00a0|\00a0"; }
311 | #header #revnumber { text-transform: capitalize; }
312 | #header #revnumber:after { content: "\00a0"; }
313 |
314 | #content > h1:first-child:not([class]) { color: #7b2d00; border-bottom: 1px solid #dddddd; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; }
315 |
316 | #toc { border-bottom: 0 solid #dddddd; padding-bottom: 0.5em; }
317 | #toc > ul { margin-left: 0.125em; }
318 | #toc ul.sectlevel0 > li > a { font-style: italic; }
319 | #toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; }
320 | #toc ul { font-family: Arial, sans-serif; list-style-type: none; }
321 | #toc a { text-decoration: none; }
322 | #toc a:active { text-decoration: underline; }
323 |
324 | #toctitle { color: #003b6b; font-size: 1.2em; }
325 |
326 | @media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; }
327 | body.toc2 { padding-left: 15em; padding-right: 0; }
328 | #toc.toc2 { margin-top: 0 !important; background-color: white; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
329 | #toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
330 | #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; }
331 | #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
332 | #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
333 | body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
334 | body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } }
335 | @media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
336 | #toc.toc2 { width: 20em; }
337 | #toc.toc2 #toctitle { font-size: 1.375em; }
338 | #toc.toc2 > ul { font-size: 0.95em; }
339 | #toc.toc2 ul ul { padding-left: 1.25em; }
340 | body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
341 | #content #toc { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
342 | #content #toc > :first-child { margin-top: 0; }
343 | #content #toc > :last-child { margin-bottom: 0; }
344 |
345 | #footer { max-width: 100%; background-color: none; padding: 1.25em; }
346 |
347 | #footer-text { color: black; line-height: 1.44; }
348 |
349 | .sect1 { padding-bottom: 0.625em; }
350 |
351 | @media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } }
352 | .sect1 + .sect1 { border-top: 0 solid #dddddd; }
353 |
354 | #content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; }
355 | #content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; }
356 | #content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }
357 | #content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #7b2d00; text-decoration: none; }
358 | #content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #622400; }
359 |
360 | .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; }
361 |
362 | .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; }
363 |
364 | table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
365 |
366 | .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: #7b2d00; }
367 |
368 | table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
369 |
370 | .admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; }
371 | .admonitionblock > table td.icon { text-align: center; width: 80px; }
372 | .admonitionblock > table td.icon img { max-width: none; }
373 | .admonitionblock > table td.icon .title { font-weight: bold; font-family: Arial, sans-serif; text-transform: uppercase; }
374 | .admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #e15200; }
375 | .admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
376 |
377 | .exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
378 | .exampleblock > .content > :first-child { margin-top: 0; }
379 | .exampleblock > .content > :last-child { margin-bottom: 0; }
380 |
381 | .sidebarblock { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
382 | .sidebarblock > :first-child { margin-top: 0; }
383 | .sidebarblock > :last-child { margin-bottom: 0; }
384 | .sidebarblock > .content > .title { color: #003b6b; margin-top: 0; }
385 |
386 | .exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
387 |
388 | .literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eeeeee; }
389 | .sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; }
390 |
391 | .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px dashed #666666; -webkit-border-radius: 0; border-radius: 0; word-wrap: break-word; padding: 1.25em 1.5625em 1.125em 1.5625em; font-size: 0.8125em; }
392 | .literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
393 | @media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } }
394 | @media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } }
395 |
396 | .literalblock.output pre { color: #eeeeee; background-color: black; }
397 |
398 | .listingblock pre.highlightjs { padding: 0; }
399 | .listingblock pre.highlightjs > code { padding: 1.25em 1.5625em 1.125em 1.5625em; -webkit-border-radius: 0; border-radius: 0; }
400 |
401 | .listingblock > .content { position: relative; }
402 |
403 | .listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; }
404 |
405 | .listingblock:hover code[data-lang]:before { display: block; }
406 |
407 | .listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
408 |
409 | .listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; }
410 |
411 | table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; }
412 |
413 | table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
414 |
415 | table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
416 |
417 | pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; }
418 |
419 | pre.pygments .lineno { display: inline-block; margin-right: .25em; }
420 |
421 | table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; }
422 |
423 | .quoteblock { margin: 0 1em 0.75em 1.5em; display: table; }
424 | .quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; }
425 | .quoteblock blockquote, .quoteblock blockquote p { color: #333333; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; }
426 | .quoteblock blockquote { margin: 0; padding: 0; border: 0; }
427 | .quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #003b6b; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); }
428 | .quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
429 | .quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; }
430 | .quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #e15200; }
431 | .quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; }
432 | .quoteblock .quoteblock blockquote:before { display: none; }
433 |
434 | .verseblock { margin: 0 1em 0.75em 1em; }
435 | .verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #333333; font-weight: 300; text-rendering: optimizeLegibility; }
436 | .verseblock pre strong { font-weight: 400; }
437 | .verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; }
438 |
439 | .quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; }
440 | .quoteblock .attribution br, .verseblock .attribution br { display: none; }
441 | .quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.05em; color: #e15200; }
442 |
443 | .quoteblock.abstract { margin: 0 0 0.75em 0; display: block; }
444 | .quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; }
445 | .quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; }
446 |
447 | table.tableblock { max-width: 100%; border-collapse: separate; }
448 | table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
449 |
450 | table.spread { width: 100%; }
451 |
452 | table.tableblock, th.tableblock, td.tableblock { border: 0 solid #d8d8ce; }
453 |
454 | table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; }
455 |
456 | table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
457 |
458 | table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
459 |
460 | table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
461 |
462 | table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
463 |
464 | table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; }
465 |
466 | table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
467 |
468 | table.frame-all { border-width: 1px; }
469 |
470 | table.frame-sides { border-width: 0 1px; }
471 |
472 | table.frame-topbot { border-width: 1px 0; }
473 |
474 | th.halign-left, td.halign-left { text-align: left; }
475 |
476 | th.halign-right, td.halign-right { text-align: right; }
477 |
478 | th.halign-center, td.halign-center { text-align: center; }
479 |
480 | th.valign-top, td.valign-top { vertical-align: top; }
481 |
482 | th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
483 |
484 | th.valign-middle, td.valign-middle { vertical-align: middle; }
485 |
486 | table thead th, table tfoot th { font-weight: bold; }
487 |
488 | tbody tr th { display: table-cell; line-height: 1.4; background: -webkit-linear-gradient(top, #add386, #90b66a); }
489 |
490 | tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: white; font-weight: bold; }
491 |
492 | p.tableblock > code:only-child { background: none; padding: 0; }
493 |
494 | p.tableblock { font-size: 1em; }
495 |
496 | td > div.verse { white-space: pre; }
497 |
498 | ol { margin-left: 1.75em; }
499 |
500 | ul li ol { margin-left: 1.5em; }
501 |
502 | dl dd { margin-left: 1.125em; }
503 |
504 | dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }
505 |
506 | ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.375em; }
507 |
508 | ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
509 |
510 | ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
511 |
512 | ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; }
513 |
514 | ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; }
515 |
516 | ul.inline { margin: 0 auto 0.375em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
517 | ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
518 | ul.inline > li > * { display: block; }
519 |
520 | .unstyled dl dt { font-weight: normal; font-style: normal; }
521 |
522 | ol.arabic { list-style-type: decimal; }
523 |
524 | ol.decimal { list-style-type: decimal-leading-zero; }
525 |
526 | ol.loweralpha { list-style-type: lower-alpha; }
527 |
528 | ol.upperalpha { list-style-type: upper-alpha; }
529 |
530 | ol.lowerroman { list-style-type: lower-roman; }
531 |
532 | ol.upperroman { list-style-type: upper-roman; }
533 |
534 | ol.lowergreek { list-style-type: lower-greek; }
535 |
536 | .hdlist > table, .colist > table { border: 0; background: none; }
537 | .hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
538 |
539 | td.hdlist1 { padding-right: .75em; font-weight: bold; }
540 |
541 | td.hdlist1, td.hdlist2 { vertical-align: top; }
542 |
543 | .literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
544 |
545 | .colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; }
546 | .colist > table tr > td:last-of-type { padding: 0.25em 0; }
547 |
548 | .thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
549 |
550 | .imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
551 | .imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
552 | .imageblock > .title { margin-bottom: 0; }
553 | .imageblock.thumb, .imageblock.th { border-width: 6px; }
554 | .imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
555 |
556 | .image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
557 | .image.left { margin-right: 0.625em; }
558 | .image.right { margin-left: 0.625em; }
559 |
560 | a.image { text-decoration: none; }
561 |
562 | span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
563 | span.footnote a, span.footnoteref a { text-decoration: none; }
564 | span.footnote a:active, span.footnoteref a:active { text-decoration: underline; }
565 |
566 | #footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
567 | #footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
568 | #footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
569 | #footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
570 | #footnotes .footnote:last-of-type { margin-bottom: 0; }
571 |
572 | #content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
573 |
574 | .gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; }
575 | .gist .file-data > table td.line-data { width: 99%; }
576 |
577 | div.unbreakable { page-break-inside: avoid; }
578 |
579 | .big { font-size: larger; }
580 |
581 | .small { font-size: smaller; }
582 |
583 | .underline { text-decoration: underline; }
584 |
585 | .overline { text-decoration: overline; }
586 |
587 | .line-through { text-decoration: line-through; }
588 |
589 | .aqua { color: #00bfbf; }
590 |
591 | .aqua-background { background-color: #00fafa; }
592 |
593 | .black { color: black; }
594 |
595 | .black-background { background-color: black; }
596 |
597 | .blue { color: #0000bf; }
598 |
599 | .blue-background { background-color: #0000fa; }
600 |
601 | .fuchsia { color: #bf00bf; }
602 |
603 | .fuchsia-background { background-color: #fa00fa; }
604 |
605 | .gray { color: #606060; }
606 |
607 | .gray-background { background-color: #7d7d7d; }
608 |
609 | .green { color: #006000; }
610 |
611 | .green-background { background-color: #007d00; }
612 |
613 | .lime { color: #00bf00; }
614 |
615 | .lime-background { background-color: #00fa00; }
616 |
617 | .maroon { color: #600000; }
618 |
619 | .maroon-background { background-color: #7d0000; }
620 |
621 | .navy { color: #000060; }
622 |
623 | .navy-background { background-color: #00007d; }
624 |
625 | .olive { color: #606000; }
626 |
627 | .olive-background { background-color: #7d7d00; }
628 |
629 | .purple { color: #600060; }
630 |
631 | .purple-background { background-color: #7d007d; }
632 |
633 | .red { color: #bf0000; }
634 |
635 | .red-background { background-color: #fa0000; }
636 |
637 | .silver { color: #909090; }
638 |
639 | .silver-background { background-color: #bcbcbc; }
640 |
641 | .teal { color: #006060; }
642 |
643 | .teal-background { background-color: #007d7d; }
644 |
645 | .white { color: #bfbfbf; }
646 |
647 | .white-background { background-color: #fafafa; }
648 |
649 | .yellow { color: #bfbf00; }
650 |
651 | .yellow-background { background-color: #fafa00; }
652 |
653 | span.icon > .fa { cursor: default; }
654 |
655 | .admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; }
656 | .admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #004176; }
657 | .admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }
658 | .admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; }
659 | .admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; }
660 | .admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; }
661 |
662 | .conum[data-value] { display: inline-block; color: #fff !important; background-color: black; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; }
663 | .conum[data-value] * { color: #fff !important; }
664 | .conum[data-value] + b { display: none; }
665 | .conum[data-value]:after { content: attr(data-value); }
666 | pre .conum[data-value] { position: relative; top: -0.125em; }
667 |
668 | b.conum * { color: inherit !important; }
669 |
670 | .conum:not([data-value]):empty { display: none; }
671 |
672 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { border-bottom: 1px solid #dddddd; }
673 |
674 | .sect1 { padding-bottom: 0; }
675 |
676 | #toctitle { color: #00406F; font-weight: normal; margin-top: 1.5em; }
677 |
678 | .sidebarblock { border-color: #aaa; }
679 |
680 | code { -webkit-border-radius: 4px; border-radius: 4px; }
681 |
682 | p.tableblock.header { color: #6d6e71; }
683 |
684 | .literalblock pre, .listingblock pre { background: #eeeeee; }
685 |
--------------------------------------------------------------------------------
/doc/enums.adoc:
--------------------------------------------------------------------------------
1 |
2 | [[enums]]
3 | == Enums
4 |
5 | [[channels]]
6 | [small]#*channels*: '_y_' (grey), '_ya_' (grey alpha), '_rgb_', '_rgba_'. +
7 | Notice that _#channels_ gives the number of channels (e.g. #_'rgb'_ = 3 channels).#
8 |
9 | [[chantype]]
10 | [small]#*chantype*: '_u8_', '_u16_', '_f_'.#
11 |
12 |
--------------------------------------------------------------------------------
/doc/index.adoc:
--------------------------------------------------------------------------------
1 | = MoonImage Reference Manual
2 | Stefano Trettel
3 | v0.3, 2020-04-21
4 | :toc: left
5 | :toclevels: 2
6 | :stylesdir: ./
7 | :stylesheet: colony.css
8 | :source-highlighter: pygments
9 | :pygments-style: autumn
10 | :source-language: lua
11 | :exampledir: ../examples
12 |
13 | image::powered-by-lua.gif[Lua logo, link=http://www.lua.org]
14 |
15 | // Macros for trees: {tS} = " ", {tI} = "│ ", {tH} = "├─ ", {tL} = "└─ "
16 | :tS:
17 | :tI: │
18 | :tH: ├─
19 | :tL: └─
20 |
21 | include::preface.adoc[]
22 |
23 | include::load.adoc[]
24 | include::write.adoc[]
25 | include::perlin.adoc[]
26 | include::enums.adoc[]
27 |
28 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | MoonImage Reference Manual
10 |
697 |
765 |
766 |
767 |
793 |
794 |
795 |
796 |
797 |
798 |

799 |
800 |
801 |
802 |
803 |
804 |
Preface
805 |
806 |
807 |
This is the reference manual of MoonImage, which is a
808 | Lua image loading library based on Sean Barrett’s
809 | STB libraries.
810 |
811 |
812 |
813 |
It is assumed that the reader is familiar with the Lua programming language.
814 |
815 |
816 |
For convenience of reference, this document contains external (deep) links to the
817 | Lua Reference Manual.
818 |
819 |
820 |
Getting and installing
821 |
826 |
827 |
828 |
Module organization
829 |
830 |
The MoonImage module is loaded using Lua’s
831 | require() and
832 | returns a table containing the functions it provides
833 | (as usual with Lua modules). This manual assumes that such
834 | table is named mi, i.e. that it is loaded with:
835 |
836 |
837 |
838 |
mi = require("image")
839 |
840 |
841 |
842 |
but nothing forbids the use of a different name.
843 |
844 |
845 |
846 |
Examples
847 |
848 |
Complete examples can be found in the examples/ directory of the release package.
849 |
850 |
851 |
852 |
License
853 |
854 |
MoonImage is released under the MIT/X11 license (same as
855 | Lua, and with the same only requirement to give proper
856 | credits to the original author).
857 | The copyright notice is in the LICENSE file in the base directory
858 | of the official repository on GitHub.
859 |
860 |
861 |
862 |
See also
863 |
864 |
MoonImage is part of MoonLibs, a collection of
865 | Lua libraries for graphics and audio programming.
866 |
867 |
868 |
869 |
870 |
871 |
Load images
872 |
873 |
876 |
877 |
878 | -
879 |
data, w, h, channels = load(filename, [desiredchannels], [chantype])
880 | Loads an image from a file, and returns the image data, its width w and height h, and the color channels contained in data (which is the same as desiredchannels unless this is nil, in which case channels is the same as in the image file).
881 | The returned data is a binary string containing w*h pixels, each pixel consisting of up to 4 interleaved components (one per channel).
882 | The type of the components is determined by the chantype parameter:
883 | -if chantype is 'u8' or nil, then each component is an unsigned 8 bit integer;
884 | -if chantype is 'u16', then each component is an unsigned 16 bit integer;
885 | -if chantype is 'f', then each component is a single precision float value.
886 | Note that this may involve lossy data conversion if chantype does not match how data is stored
887 | in the image file.
888 | (u16 values are converted to u8 by just keeping the MSB, u8 values
889 | are converted to u16 by mapping x to x*28+x, while conversion to or from floats is done
890 | using gamma correction with the current gamma and scale values.)
891 |
892 |
893 |
894 |
902 |
910 |
911 |
912 | -
913 |
set_gamma_and_scale(gamma, scale)
914 | gamma, scale = gamma_and_scale( )
915 | Set/get the gamma and scale values used in gamma correction (by default, gamma = 2.2 and scale = 1.0).
916 |
917 |
918 |
919 |
929 |
937 |
938 |
939 | -
940 |
data = reduce_to_u8(data, w, h, channels, chantype)
941 | Downgrades 'u16' or 'f' image data to 'u8' (see load( )).
942 |
943 |
944 |
945 |
946 |
947 |
948 |
Write images
949 |
950 |
953 |
954 |
955 | -
956 |
write_png(filename, w, h, channels, data, [stride])
957 | Write data to a PNG file.
958 | Expects w*h*#channels bytes of data.
959 |
960 |
961 |
962 |
963 |
964 | -
965 |
write_bmp(filename, w, h, channels, data)
966 | Write data to a BMP file.
967 | Expects w*h*#channels bytes of data.
968 |
969 |
970 |
971 |
972 |
973 | -
974 |
write_tga(filename, w, h, channels, data, [rle])
975 | Write data to a TGA file.
976 | Expects w*h*#channels bytes of data.
977 | Pass rle = true to use RLE compression.
978 |
979 |
980 |
981 |
982 |
983 | -
984 |
write_jpg(filename, w, h, channels, data, quality)
985 | Write data to a JPG file.
986 | Expects w*h*#channels bytes of data.
987 | quality = 1 (min) .. 100 (max).
988 |
989 |
990 |
991 |
992 |
993 | -
994 |
write_hdr(filename, w, h, channels, data)
995 | Write data to a HDR file.
996 | Expects w*h*#channels*sizeof(float) bytes of data.
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
Perlin noise
1004 |
1005 |
1008 |
1009 |
1010 | -
1011 |
value = perlin(x, [y, z, xwrap, ywrap, zwrap, seed])
1012 | Computes a random value at coordinates (x, y, z).
1013 | Binding to stb_perlin_noise3_seed( ). See stb_perlin.h for details.
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
Enums
1021 |
1022 |
1023 |
channels: 'y' (grey), 'ya' (grey alpha), 'rgb', 'rgba'.
1024 | Notice that #channels gives the number of channels (e.g. #'rgb' = 3 channels).
1025 |
1026 |
1027 |
chantype: 'u8', 'u16', 'f'.
1028 |
1029 |
1030 |
1031 |
1032 |
1038 |
1044 |
1045 |
--------------------------------------------------------------------------------
/doc/load.adoc:
--------------------------------------------------------------------------------
1 |
2 | == Load images
3 |
4 | [small]#Rfr: https://github.com/nothings/stb[stb_image.h]#
5 |
6 | [[load]]
7 | * _data_, _w_, _h_, <> = *load*(_filename_, [<>], [<>]) +
8 | [small]#Loads an image from a file, and returns the image _data_, its width _w_ and height _h_, and the color _channels_ contained in _data_ (which is the same as _desiredchannels_ unless this is _nil_, in which case _channels_ is the same as in the image file). +
9 | The returned _data_ is a binary string containing _w*h_ pixels, each pixel consisting of up to 4 interleaved components (one per channel). +
10 | The type of the components is determined by the _chantype_ parameter: +
11 | pass:[-]if _chantype_ is '_u8_' or _nil_, then each component is an unsigned 8 bit integer; +
12 | pass:[-]if _chantype_ is '_u16_', then each component is an unsigned 16 bit integer; +
13 | pass:[-]if _chantype_ is '_f_', then each component is a single precision float value. +
14 | Note that this may involve lossy data conversion if _chantype_ does not match how data is stored
15 | in the image file. +
16 | (_u16_ values are converted to _u8_ by just keeping the MSB, _u8_ values
17 | are converted to _u16_ by mapping _x_ to _x*2^8^+x_, while conversion to or from floats is done
18 | using gamma correction with the current <> values.)#
19 |
20 | ////
21 | u8 <-> u18 conversions:
22 | u8->u16 x -> (x>>8) & 0xff (MSB as 8bit approximation of a 16 bit value)
23 | u16->u8 x -> (x<<8) + x (map 0->0 and 255->0xffff)
24 | ////
25 |
26 | [[info]]
27 | * _w_, _h_, <> = *info*(_filename_) +
28 | [small]#Retrieves information for an image without loading it.#
29 |
30 | [[is_hdr]]
31 | * _boolean_ = *is_hdr*(_filename_) +
32 | [small]#Returns _true_ the image contained in _filename_ is HDR (High Dynamic Range).#
33 |
34 | [[gamma_and_scale]]
35 | * *set_gamma_and_scale*(_gamma_, _scale_) +
36 | _gamma_, _scale_ = *gamma_and_scale*( ) +
37 | [small]#Set/get the _gamma_ and _scale_ values used in https://en.wikipedia.org/wiki/Gamma_correction[gamma correction] (by default, _gamma = 2.2_ and _scale = 1.0_).#
38 |
39 | [[load_flags]]
40 | * *flip_vertically_on_load*(_boolean_) +
41 | *unpremultiply_on_load*(_boolean_) +
42 | *convert_iphone_png_to_rgb*(_boolean_) +
43 | [small]#Load flags that control a few aspects of how an image is loaded (see https://github.com/nothings/stb[stb_image.h] for more details).#
44 |
45 |
46 | [[reset_load_flags]]
47 | * *reset_load_flags*( ) +
48 | [small]#Resets all the <> to _false_ (which is also their initial value).#
49 |
50 | [[reduce_to_u8]]
51 | * _data_ = *reduce_to_u8*(_data_, _w_, _h_, <>, <>) +
52 | [small]#Downgrades '_u16_' or '_f_' image data to '_u8_' (see <>( )).#
53 |
54 | ////
55 | [[]]
56 | * **( ) +
57 | [small]#@@TODO.#
58 | ////
59 |
60 |
--------------------------------------------------------------------------------
/doc/perlin.adoc:
--------------------------------------------------------------------------------
1 |
2 | [[Write]]
3 | == Perlin noise
4 |
5 | [small]#Rfr: https://github.com/nothings/stb[stb_perlin.h]#
6 |
7 | [[perlin]]
8 | * _value_ = *perlin*(_x_, [_y_, _z_, _xwrap_, _ywrap_, _zwrap_, _seed_]) +
9 | [small]#Computes a random value at coordinates _(x, y, z)_. +
10 | Binding to _stb_perlin_noise3_seed( )_. See stb_perlin.h for details.#
11 |
12 |
--------------------------------------------------------------------------------
/doc/powered-by-lua.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stetre/moonimage/6d8bbb75ff47429c426e61e59aada3950e2b2217/doc/powered-by-lua.gif
--------------------------------------------------------------------------------
/doc/preface.adoc:
--------------------------------------------------------------------------------
1 |
2 | == Preface
3 |
4 | This is the reference manual of *MoonImage*, which is a
5 | http://www.lua.org[*Lua*] image loading library based on Sean Barrett's
6 | https://github.com/nothings/stb[*STB libraries*].
7 | footnote:[
8 | This manual is written in
9 | http://www.methods.co.nz/asciidoc/[AsciiDoc], rendered with
10 | http://asciidoctor.org/[AsciiDoctor] and a CSS from the
11 | https://github.com/asciidoctor/asciidoctor-stylesheet-factory[AsciiDoctor Stylesheet Factory].]
12 |
13 | It is assumed that the reader is familiar with the Lua programming language.
14 |
15 | For convenience of reference, this document contains external (deep) links to the
16 | http://www.lua.org/manual/5.3/manual.html[Lua Reference Manual].
17 |
18 | === Getting and installing
19 |
20 | For installation intructions, refer to the README file in the
21 | https://github.com/stetre/image[*MoonImage official repository*]
22 | on GitHub.
23 |
24 | === Module organization
25 |
26 | The MoonImage module is loaded using Lua's
27 | http://www.lua.org/manual/5.3/manual.html#pdf-require[require]() and
28 | returns a table containing the functions it provides
29 | (as usual with Lua modules). This manual assumes that such
30 | table is named *mi*, i.e. that it is loaded with:
31 |
32 | [source,lua,indent=1]
33 | ----
34 | mi = require("image")
35 | ----
36 |
37 | but nothing forbids the use of a different name.
38 |
39 | === Examples
40 |
41 | Complete examples can be found in the *examples/* directory of the release package.
42 |
43 | === License
44 |
45 | MoonImage is released under the *MIT/X11 license* (same as
46 | http://www.lua.org/license.html[Lua], and with the same only requirement to give proper
47 | credits to the original author).
48 | The copyright notice is in the LICENSE file in the base directory
49 | of the https://github.com/stetre/moonimage[official repository] on GitHub.
50 |
51 | [[see-also]]
52 | === See also
53 |
54 | MoonImage is part of https://github.com/stetre/moonlibs[MoonLibs], a collection of
55 | Lua libraries for graphics and audio programming.
56 |
57 |
--------------------------------------------------------------------------------
/doc/write.adoc:
--------------------------------------------------------------------------------
1 |
2 | [[Write]]
3 | == Write images
4 |
5 | [small]#Rfr: https://github.com/nothings/stb[stb_image_write.h]#
6 |
7 | [[write_png]]
8 | * *write_png*(_filename_, _w_, _h_, <>, _data_, [_stride_]) +
9 | [small]#Write data to a https://en.wikipedia.org/wiki/Portable_Network_Graphics[PNG] file.
10 | Expects _w*h*#channels_ bytes of _data_.#
11 |
12 | [[write_bmp]]
13 | * *write_bmp*(_filename_, _w_, _h_, <>, _data_) +
14 | [small]#Write data to a https://en.wikipedia.org/wiki/BMP_file_format[BMP] file.
15 | Expects _w*h*#channels_ bytes of _data_.#
16 |
17 | [[write_tga]]
18 | * *write_tga*(_filename_, _w_, _h_, <>, _data_, [_rle_]) +
19 | [small]#Write data to a https://en.wikipedia.org/wiki/Truevision_TGA[TGA] file.
20 | Expects _w*h*#channels_ bytes of _data_. +
21 | Pass _rle_ = _true_ to use RLE compression.#
22 |
23 | [[write_jpg]]
24 | * *write_jpg*(_filename_, _w_, _h_, <>, _data_, _quality_) +
25 | [small]#Write data to a https://en.wikipedia.org/wiki/JPEG[JPG] file.
26 | Expects _w*h*#channels_ bytes of _data_. +
27 | _quality = 1 (min) .. 100 (max)_.#
28 |
29 | [[write_hdr]]
30 | * *write_hdr*(_filename_, _w_, _h_, <>, _data_) +
31 | [small]#Write data to a https://en.wikipedia.org/wiki/Radiance_(software)#HDR_image_format[HDR] file.
32 | Expects _w*h*#channels*sizeof(float)_ bytes of _data_.#
33 |
--------------------------------------------------------------------------------
/examples/hello.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env lua
2 | -- MoonImage example: hello.lua
3 |
4 | mi = require("moonimage")
5 |
6 | -- Load an image from a jpg file:
7 | data, w, h, channels = mi.load("sunflowers.jpg", 'rgba')
8 |
9 | -- Write it to a bmp file:
10 | mi.write_bmp("output.bmp", w, h, channels, data)
11 |
12 |
--------------------------------------------------------------------------------
/examples/sunflowers.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stetre/moonimage/6d8bbb75ff47429c426e61e59aada3950e2b2217/examples/sunflowers.jpg
--------------------------------------------------------------------------------
/examples/version.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env lua
2 |
3 | mi = require("moonimage")
4 |
5 | print(mi._VERSION)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/moonimage/README:
--------------------------------------------------------------------------------
1 |
2 | This directory should contain any additional utility implemented in pure Lua.
3 |
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 |
2 | ifdef MINGW_PREFIX
3 | MINGW=1
4 | else
5 | LINUX=1
6 | endif
7 |
8 | # Lua version
9 | LUAVER?=$(shell lua -e 'print(string.match(_VERSION, "%d+%.%d+") or "5.3")')
10 | ifeq ($(LUAVER),)
11 | # lua-interpreter not found
12 | LUAVER=5.3
13 | endif
14 |
15 | # Base install directory
16 | ifdef LINUX
17 | PREFIX?=/usr/local
18 | endif
19 | ifdef MINGW
20 | PREFIX?=$(MINGW_PREFIX)
21 | endif
22 |
23 | # Directory where to install Lua modules
24 | L_DIR=$(PREFIX)/share/lua/$(LUAVER)
25 | # Directory where to install Lua C modules
26 | C_DIR=$(PREFIX)/lib/lua/$(LUAVER)
27 | # Directory where to install C headers
28 | H_DIR=$(PREFIX)/include
29 | # Directory where to install C libraries
30 | S_DIR=$(PREFIX)/lib
31 |
32 | ifeq ($(D),1)
33 | DEBUG=1
34 | endif
35 |
36 | Tgt := moonimage
37 | Src := $(wildcard *.c)
38 | Objs := $(Src:.c=.o)
39 |
40 | COPT += -O2
41 | #COPT += -O0 -g
42 | #COPT += -m32
43 | COPT += -Wall -Wextra -Wpedantic
44 | COPT += -DCOMPAT53_PREFIX=moonimage_compat_
45 | COPT += -Wno-unused-function -Wno-implicit-fallthrough #@@
46 | COPT += -std=gnu99
47 | COPT += -DLUAVER=$(LUAVER)
48 | ifdef LINUX
49 | COPT += -fpic
50 | COPT += -DLINUX
51 | INCDIR = -I./include -I/usr/include/lua$(LUAVER)
52 | endif
53 | ifdef MINGW
54 | COPT += -DMINGW
55 | INCDIR = -I./include
56 | LIBS = -llua
57 | endif
58 | ifdef DEBUG
59 | COPT += -DDEBUG
60 | COPT += -Wshadow -Wsign-compare -Wundef -Wwrite-strings
61 | COPT += -Wdisabled-optimization -Wdeclaration-after-statement
62 | COPT += -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs
63 | COPT += -Wc++-compat -Wold-style-definition
64 | endif
65 |
66 | override CFLAGS = $(COPT) $(INCDIR)
67 |
68 | default: build
69 |
70 | where:
71 | @echo "PREFIX="$(PREFIX)
72 | @echo "LUAVER="$(LUAVER)
73 | @echo $(L_DIR)
74 | @echo $(C_DIR)
75 | @echo $(H_DIR)
76 | @echo $(S_DIR)
77 |
78 | clean:
79 | @-rm -f *.so *.dll *.o *.err *.map *.S *~ *.log
80 | @-rm -f $(Tgt).symbols
81 |
82 | install:
83 | @-mkdir -pv $(H_DIR)
84 | @-mkdir -pv $(C_DIR)
85 | @-mkdir -pv $(S_DIR)
86 | @-mkdir -pv $(L_DIR)
87 | @-cp -fpv $(Tgt).h $(H_DIR)
88 | @-cp -fpvr ../$(Tgt) $(L_DIR)
89 | ifdef LINUX
90 | @-cp -fpv $(Tgt).so $(C_DIR)
91 | @-ln -fsv $(C_DIR)/$(Tgt).so $(S_DIR)/lib$(Tgt).so
92 | endif
93 | ifdef MINGW
94 | @-cp -fpv $(Tgt).dll $(C_DIR)
95 | endif
96 |
97 | uninstall:
98 | @-rm -f $(H_DIR)/$(Tgt).h
99 | @-rm -f $(C_DIR)/$(Tgt).so
100 | @-rm -f $(S_DIR)/lib$(Tgt).so
101 | @-rm -fr $(L_DIR)/$(Tgt)
102 | @-rm -f $(C_DIR)/$(Tgt).dll
103 |
104 | build: clean $(Tgt)
105 |
106 | symbols: build
107 | @objdump -T $(Tgt).so > $(Tgt).symbols
108 |
109 | $(Tgt): $(Objs)
110 | ifdef LINUX
111 | @-$(CC) -shared -o $(Tgt).so $(Objs) $(LIBDIR) $(LIBS)
112 | endif
113 | ifdef MINGW
114 | @-$(CC) -shared -o $(Tgt).dll $(Objs) $(LIBDIR) $(LIBS)
115 | endif
116 | @-rm -f $(Objs)
117 | @echo
118 |
119 |
--------------------------------------------------------------------------------
/src/_make:
--------------------------------------------------------------------------------
1 | make D=$1 LUAVER=5.4 && sudo make LUAVER=5.4 install
2 |
--------------------------------------------------------------------------------
/src/compat-5.3.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "compat-5.3.h"
8 |
9 | /* don't compile it again if it already is included via compat53.h */
10 | #ifndef COMPAT53_C_
11 | #define COMPAT53_C_
12 |
13 |
14 |
15 | /* definitions for Lua 5.1 only */
16 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
17 |
18 | #ifndef COMPAT53_FOPEN_NO_LOCK
19 | # if defined(_MSC_VER)
20 | # define COMPAT53_FOPEN_NO_LOCK 1
21 | # else /* otherwise */
22 | # define COMPAT53_FOPEN_NO_LOCK 0
23 | # endif /* VC++ only so far */
24 | #endif /* No-lock fopen_s usage if possible */
25 |
26 | #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
27 | # include
28 | #endif /* VC++ _fsopen for share-allowed file read */
29 |
30 | #ifndef COMPAT53_HAVE_STRERROR_R
31 | # if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
32 | (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) || \
33 | defined(__APPLE__)
34 | # define COMPAT53_HAVE_STRERROR_R 1
35 | # else /* none of the defines matched: define to 0 */
36 | # define COMPAT53_HAVE_STRERROR_R 0
37 | # endif /* have strerror_r of some form */
38 | #endif /* strerror_r */
39 |
40 | #ifndef COMPAT53_HAVE_STRERROR_S
41 | # if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
42 | defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
43 | # define COMPAT53_HAVE_STRERROR_S 1
44 | # else /* not VC++ or C11 */
45 | # define COMPAT53_HAVE_STRERROR_S 0
46 | # endif /* strerror_s from VC++ or C11 */
47 | #endif /* strerror_s */
48 |
49 | #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE
50 | # define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
51 | #endif /* Lua File Buffer Size */
52 |
53 |
54 | static char* compat53_strerror (int en, char* buff, size_t sz) {
55 | #if COMPAT53_HAVE_STRERROR_R
56 | /* use strerror_r here, because it's available on these specific platforms */
57 | if (sz > 0) {
58 | buff[0] = '\0';
59 | /* we don't care whether the GNU version or the XSI version is used: */
60 | if (strerror_r(en, buff, sz)) {
61 | /* Yes, we really DO want to ignore the return value!
62 | * GCC makes that extra hard, not even a (void) cast will do. */
63 | }
64 | if (buff[0] == '\0') {
65 | /* Buffer is unchanged, so we probably have called GNU strerror_r which
66 | * returned a static constant string. Chances are that strerror will
67 | * return the same static constant string and therefore be thread-safe. */
68 | return strerror(en);
69 | }
70 | }
71 | return buff; /* sz is 0 *or* strerror_r wrote into the buffer */
72 | #elif COMPAT53_HAVE_STRERROR_S
73 | /* for MSVC and other C11 implementations, use strerror_s since it's
74 | * provided by default by the libraries */
75 | strerror_s(buff, sz, en);
76 | return buff;
77 | #else
78 | /* fallback, but strerror is not guaranteed to be threadsafe due to modifying
79 | * errno itself and some impls not locking a static buffer for it ... but most
80 | * known systems have threadsafe errno: this might only change if the locale
81 | * is changed out from under someone while this function is being called */
82 | (void)buff;
83 | (void)sz;
84 | return strerror(en);
85 | #endif
86 | }
87 |
88 |
89 | COMPAT53_API int lua_absindex (lua_State *L, int i) {
90 | if (i < 0 && i > LUA_REGISTRYINDEX)
91 | i += lua_gettop(L) + 1;
92 | return i;
93 | }
94 |
95 |
96 | static void compat53_call_lua (lua_State *L, char const code[], size_t len,
97 | int nargs, int nret) {
98 | lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
99 | if (lua_type(L, -1) != LUA_TFUNCTION) {
100 | lua_pop(L, 1);
101 | if (luaL_loadbuffer(L, code, len, "=none"))
102 | lua_error(L);
103 | lua_pushvalue(L, -1);
104 | lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
105 | }
106 | lua_insert(L, -nargs-1);
107 | lua_call(L, nargs, nret);
108 | }
109 |
110 |
111 | static const char compat53_arith_code[] =
112 | "local op,a,b=...\n"
113 | "if op==0 then return a+b\n"
114 | "elseif op==1 then return a-b\n"
115 | "elseif op==2 then return a*b\n"
116 | "elseif op==3 then return a/b\n"
117 | "elseif op==4 then return a%b\n"
118 | "elseif op==5 then return a^b\n"
119 | "elseif op==6 then return -a\n"
120 | "end\n";
121 |
122 | COMPAT53_API void lua_arith (lua_State *L, int op) {
123 | if (op < LUA_OPADD || op > LUA_OPUNM)
124 | luaL_error(L, "invalid 'op' argument for lua_arith");
125 | luaL_checkstack(L, 5, "not enough stack slots");
126 | if (op == LUA_OPUNM)
127 | lua_pushvalue(L, -1);
128 | lua_pushnumber(L, op);
129 | lua_insert(L, -3);
130 | compat53_call_lua(L, compat53_arith_code,
131 | sizeof(compat53_arith_code)-1, 3, 1);
132 | }
133 |
134 |
135 | static const char compat53_compare_code[] =
136 | "local a,b=...\n"
137 | "return a<=b\n";
138 |
139 | COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op) {
140 | int result = 0;
141 | switch (op) {
142 | case LUA_OPEQ:
143 | return lua_equal(L, idx1, idx2);
144 | case LUA_OPLT:
145 | return lua_lessthan(L, idx1, idx2);
146 | case LUA_OPLE:
147 | luaL_checkstack(L, 5, "not enough stack slots");
148 | idx1 = lua_absindex(L, idx1);
149 | idx2 = lua_absindex(L, idx2);
150 | lua_pushvalue(L, idx1);
151 | lua_pushvalue(L, idx2);
152 | compat53_call_lua(L, compat53_compare_code,
153 | sizeof(compat53_compare_code)-1, 2, 1);
154 | result = lua_toboolean(L, -1);
155 | lua_pop(L, 1);
156 | return result;
157 | default:
158 | luaL_error(L, "invalid 'op' argument for lua_compare");
159 | }
160 | return 0;
161 | }
162 |
163 |
164 | COMPAT53_API void lua_copy (lua_State *L, int from, int to) {
165 | int abs_to = lua_absindex(L, to);
166 | luaL_checkstack(L, 1, "not enough stack slots");
167 | lua_pushvalue(L, from);
168 | lua_replace(L, abs_to);
169 | }
170 |
171 |
172 | COMPAT53_API void lua_len (lua_State *L, int i) {
173 | switch (lua_type(L, i)) {
174 | case LUA_TSTRING:
175 | lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
176 | break;
177 | case LUA_TTABLE:
178 | if (!luaL_callmeta(L, i, "__len"))
179 | lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
180 | break;
181 | case LUA_TUSERDATA:
182 | if (luaL_callmeta(L, i, "__len"))
183 | break;
184 | /* FALLTHROUGH */
185 | default:
186 | luaL_error(L, "attempt to get length of a %s value",
187 | lua_typename(L, lua_type(L, i)));
188 | }
189 | }
190 |
191 |
192 | COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p) {
193 | int abs_i = lua_absindex(L, i);
194 | lua_pushlightuserdata(L, (void*)p);
195 | lua_rawget(L, abs_i);
196 | return lua_type(L, -1);
197 | }
198 |
199 | COMPAT53_API void lua_rawsetp (lua_State *L, int i, const void *p) {
200 | int abs_i = lua_absindex(L, i);
201 | luaL_checkstack(L, 1, "not enough stack slots");
202 | lua_pushlightuserdata(L, (void*)p);
203 | lua_insert(L, -2);
204 | lua_rawset(L, abs_i);
205 | }
206 |
207 |
208 | COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum) {
209 | lua_Number n = lua_tonumber(L, i);
210 | if (isnum != NULL) {
211 | *isnum = (n != 0 || lua_isnumber(L, i));
212 | }
213 | return n;
214 | }
215 |
216 |
217 | COMPAT53_API void luaL_checkversion (lua_State *L) {
218 | (void)L;
219 | }
220 |
221 |
222 | COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg) {
223 | if (!lua_checkstack(L, sp+LUA_MINSTACK)) {
224 | if (msg != NULL)
225 | luaL_error(L, "stack overflow (%s)", msg);
226 | else {
227 | lua_pushliteral(L, "stack overflow");
228 | lua_error(L);
229 | }
230 | }
231 | }
232 |
233 |
234 | COMPAT53_API int luaL_getsubtable (lua_State *L, int i, const char *name) {
235 | int abs_i = lua_absindex(L, i);
236 | luaL_checkstack(L, 3, "not enough stack slots");
237 | lua_pushstring(L, name);
238 | lua_gettable(L, abs_i);
239 | if (lua_istable(L, -1))
240 | return 1;
241 | lua_pop(L, 1);
242 | lua_newtable(L);
243 | lua_pushstring(L, name);
244 | lua_pushvalue(L, -2);
245 | lua_settable(L, abs_i);
246 | return 0;
247 | }
248 |
249 |
250 | COMPAT53_API lua_Integer luaL_len (lua_State *L, int i) {
251 | lua_Integer res = 0;
252 | int isnum = 0;
253 | luaL_checkstack(L, 1, "not enough stack slots");
254 | lua_len(L, i);
255 | res = lua_tointegerx(L, -1, &isnum);
256 | lua_pop(L, 1);
257 | if (!isnum)
258 | luaL_error(L, "object length is not an integer");
259 | return res;
260 | }
261 |
262 |
263 | COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
264 | luaL_checkstack(L, nup+1, "too many upvalues");
265 | for (; l->name != NULL; l++) { /* fill the table with given functions */
266 | int i;
267 | lua_pushstring(L, l->name);
268 | for (i = 0; i < nup; i++) /* copy upvalues to the top */
269 | lua_pushvalue(L, -(nup + 1));
270 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
271 | lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
272 | }
273 | lua_pop(L, nup); /* remove upvalues */
274 | }
275 |
276 |
277 | COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname) {
278 | luaL_checkstack(L, 1, "not enough stack slots");
279 | luaL_getmetatable(L, tname);
280 | lua_setmetatable(L, -2);
281 | }
282 |
283 |
284 | COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname) {
285 | void *p = lua_touserdata(L, i);
286 | luaL_checkstack(L, 2, "not enough stack slots");
287 | if (p == NULL || !lua_getmetatable(L, i))
288 | return NULL;
289 | else {
290 | int res = 0;
291 | luaL_getmetatable(L, tname);
292 | res = lua_rawequal(L, -1, -2);
293 | lua_pop(L, 2);
294 | if (!res)
295 | p = NULL;
296 | }
297 | return p;
298 | }
299 |
300 |
301 | static int compat53_countlevels (lua_State *L) {
302 | lua_Debug ar;
303 | int li = 1, le = 1;
304 | /* find an upper bound */
305 | while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
306 | /* do a binary search */
307 | while (li < le) {
308 | int m = (li + le)/2;
309 | if (lua_getstack(L, m, &ar)) li = m + 1;
310 | else le = m;
311 | }
312 | return le - 1;
313 | }
314 |
315 | static int compat53_findfield (lua_State *L, int objidx, int level) {
316 | if (level == 0 || !lua_istable(L, -1))
317 | return 0; /* not found */
318 | lua_pushnil(L); /* start 'next' loop */
319 | while (lua_next(L, -2)) { /* for each pair in table */
320 | if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
321 | if (lua_rawequal(L, objidx, -1)) { /* found object? */
322 | lua_pop(L, 1); /* remove value (but keep name) */
323 | return 1;
324 | }
325 | else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */
326 | lua_remove(L, -2); /* remove table (but keep name) */
327 | lua_pushliteral(L, ".");
328 | lua_insert(L, -2); /* place '.' between the two names */
329 | lua_concat(L, 3);
330 | return 1;
331 | }
332 | }
333 | lua_pop(L, 1); /* remove value */
334 | }
335 | return 0; /* not found */
336 | }
337 |
338 | static int compat53_pushglobalfuncname (lua_State *L, lua_Debug *ar) {
339 | int top = lua_gettop(L);
340 | lua_getinfo(L, "f", ar); /* push function */
341 | lua_pushvalue(L, LUA_GLOBALSINDEX);
342 | if (compat53_findfield(L, top + 1, 2)) {
343 | lua_copy(L, -1, top + 1); /* move name to proper place */
344 | lua_pop(L, 2); /* remove pushed values */
345 | return 1;
346 | }
347 | else {
348 | lua_settop(L, top); /* remove function and global table */
349 | return 0;
350 | }
351 | }
352 |
353 | static void compat53_pushfuncname (lua_State *L, lua_Debug *ar) {
354 | if (*ar->namewhat != '\0') /* is there a name? */
355 | lua_pushfstring(L, "function " LUA_QS, ar->name);
356 | else if (*ar->what == 'm') /* main? */
357 | lua_pushliteral(L, "main chunk");
358 | else if (*ar->what == 'C') {
359 | if (compat53_pushglobalfuncname(L, ar)) {
360 | lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
361 | lua_remove(L, -2); /* remove name */
362 | }
363 | else
364 | lua_pushliteral(L, "?");
365 | }
366 | else
367 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
368 | }
369 |
370 | #define COMPAT53_LEVELS1 12 /* size of the first part of the stack */
371 | #define COMPAT53_LEVELS2 10 /* size of the second part of the stack */
372 |
373 | COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1,
374 | const char *msg, int level) {
375 | lua_Debug ar;
376 | int top = lua_gettop(L);
377 | int numlevels = compat53_countlevels(L1);
378 | int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0;
379 | if (msg) lua_pushfstring(L, "%s\n", msg);
380 | lua_pushliteral(L, "stack traceback:");
381 | while (lua_getstack(L1, level++, &ar)) {
382 | if (level == mark) { /* too many levels? */
383 | lua_pushliteral(L, "\n\t..."); /* add a '...' */
384 | level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */
385 | }
386 | else {
387 | lua_getinfo(L1, "Slnt", &ar);
388 | lua_pushfstring(L, "\n\t%s:", ar.short_src);
389 | if (ar.currentline > 0)
390 | lua_pushfstring(L, "%d:", ar.currentline);
391 | lua_pushliteral(L, " in ");
392 | compat53_pushfuncname(L, &ar);
393 | lua_concat(L, lua_gettop(L) - top);
394 | }
395 | }
396 | lua_concat(L, lua_gettop(L) - top);
397 | }
398 |
399 |
400 | COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
401 | const char *serr = NULL;
402 | int en = errno; /* calls to Lua API may change this value */
403 | char buf[512] = { 0 };
404 | if (stat) {
405 | lua_pushboolean(L, 1);
406 | return 1;
407 | }
408 | else {
409 | lua_pushnil(L);
410 | serr = compat53_strerror(en, buf, sizeof(buf));
411 | if (fname)
412 | lua_pushfstring(L, "%s: %s", fname, serr);
413 | else
414 | lua_pushstring(L, serr);
415 | lua_pushnumber(L, (lua_Number)en);
416 | return 3;
417 | }
418 | }
419 |
420 |
421 | static int compat53_checkmode (lua_State *L, const char *mode, const char *modename, int err) {
422 | if (mode && strchr(mode, modename[0]) == NULL) {
423 | lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
424 | return err;
425 | }
426 | return LUA_OK;
427 | }
428 |
429 |
430 | typedef struct {
431 | lua_Reader reader;
432 | void *ud;
433 | int has_peeked_data;
434 | const char *peeked_data;
435 | size_t peeked_data_size;
436 | } compat53_reader_data;
437 |
438 |
439 | static const char *compat53_reader (lua_State *L, void *ud, size_t *size) {
440 | compat53_reader_data *data = (compat53_reader_data *)ud;
441 | if (data->has_peeked_data) {
442 | data->has_peeked_data = 0;
443 | *size = data->peeked_data_size;
444 | return data->peeked_data;
445 | } else
446 | return data->reader(L, data->ud, size);
447 | }
448 |
449 |
450 | COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) {
451 | int status = LUA_OK;
452 | compat53_reader_data compat53_data = { 0, NULL, 1, 0, 0 };
453 | compat53_data.reader = reader;
454 | compat53_data.ud = data;
455 | compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
456 | if (compat53_data.peeked_data && compat53_data.peeked_data_size &&
457 | compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
458 | status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
459 | else
460 | status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
461 | if (status != LUA_OK)
462 | return status;
463 | /* we need to call the original 5.1 version of lua_load! */
464 | #undef lua_load
465 | return lua_load(L, compat53_reader, &compat53_data, source);
466 | #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
467 | }
468 |
469 |
470 | typedef struct {
471 | int n; /* number of pre-read characters */
472 | FILE *f; /* file being read */
473 | char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
474 | } compat53_LoadF;
475 |
476 |
477 | static const char *compat53_getF (lua_State *L, void *ud, size_t *size) {
478 | compat53_LoadF *lf = (compat53_LoadF *)ud;
479 | (void)L; /* not used */
480 | if (lf->n > 0) { /* are there pre-read characters to be read? */
481 | *size = lf->n; /* return them (chars already in buffer) */
482 | lf->n = 0; /* no more pre-read characters */
483 | }
484 | else { /* read a block from file */
485 | /* 'fread' can return > 0 *and* set the EOF flag. If next call to
486 | 'compat53_getF' called 'fread', it might still wait for user input.
487 | The next check avoids this problem. */
488 | if (feof(lf->f)) return NULL;
489 | *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
490 | }
491 | return lf->buff;
492 | }
493 |
494 |
495 | static int compat53_errfile (lua_State *L, const char *what, int fnameindex) {
496 | char buf[512] = {0};
497 | const char *serr = compat53_strerror(errno, buf, sizeof(buf));
498 | const char *filename = lua_tostring(L, fnameindex) + 1;
499 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
500 | lua_remove(L, fnameindex);
501 | return LUA_ERRFILE;
502 | }
503 |
504 |
505 | static int compat53_skipBOM (compat53_LoadF *lf) {
506 | const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
507 | int c;
508 | lf->n = 0;
509 | do {
510 | c = getc(lf->f);
511 | if (c == EOF || c != *(const unsigned char *)p++) return c;
512 | lf->buff[lf->n++] = (char)c; /* to be read by the parser */
513 | } while (*p != '\0');
514 | lf->n = 0; /* prefix matched; discard it */
515 | return getc(lf->f); /* return next character */
516 | }
517 |
518 |
519 | /*
520 | ** reads the first character of file 'f' and skips an optional BOM mark
521 | ** in its beginning plus its first line if it starts with '#'. Returns
522 | ** true if it skipped the first line. In any case, '*cp' has the
523 | ** first "valid" character of the file (after the optional BOM and
524 | ** a first-line comment).
525 | */
526 | static int compat53_skipcomment (compat53_LoadF *lf, int *cp) {
527 | int c = *cp = compat53_skipBOM(lf);
528 | if (c == '#') { /* first line is a comment (Unix exec. file)? */
529 | do { /* skip first line */
530 | c = getc(lf->f);
531 | } while (c != EOF && c != '\n');
532 | *cp = getc(lf->f); /* skip end-of-line, if present */
533 | return 1; /* there was a comment */
534 | }
535 | else return 0; /* no comment */
536 | }
537 |
538 |
539 | COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) {
540 | compat53_LoadF lf;
541 | int status, readstatus;
542 | int c;
543 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
544 | if (filename == NULL) {
545 | lua_pushliteral(L, "=stdin");
546 | lf.f = stdin;
547 | }
548 | else {
549 | lua_pushfstring(L, "@%s", filename);
550 | #if defined(_MSC_VER)
551 | /* This code is here to stop a deprecation error that stops builds
552 | * if a certain macro is defined. While normally not caring would
553 | * be best, some header-only libraries and builds can't afford to
554 | * dictate this to the user. A quick check shows that fopen_s this
555 | * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
556 | * possibly even before that so we don't need to do any version
557 | * number checks, since this has been there since forever. */
558 |
559 | /* TO USER: if you want the behavior of typical fopen_s/fopen,
560 | * which does lock the file on VC++, define the macro used below to 0 */
561 | #if COMPAT53_FOPEN_NO_LOCK
562 | lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
563 | if (lf.f == NULL)
564 | return compat53_errfile(L, "open", fnameindex);
565 | #else /* use default locking version */
566 | if (fopen_s(&lf.f, filename, "r") != 0)
567 | return compat53_errfile(L, "open", fnameindex);
568 | #endif /* Locking vs. No-locking fopen variants */
569 | #else
570 | lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
571 | if (lf.f == NULL) return compat53_errfile(L, "open", fnameindex);
572 | #endif
573 | }
574 | if (compat53_skipcomment(&lf, &c)) /* read initial portion */
575 | lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
576 | if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
577 | #if defined(_MSC_VER)
578 | if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
579 | return compat53_errfile(L, "reopen", fnameindex);
580 | #else
581 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
582 | if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex);
583 | #endif
584 | compat53_skipcomment(&lf, &c); /* re-read initial portion */
585 | }
586 | if (c != EOF)
587 | lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */
588 | status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
589 | readstatus = ferror(lf.f);
590 | if (filename) fclose(lf.f); /* close file (even in case of errors) */
591 | if (readstatus) {
592 | lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
593 | return compat53_errfile(L, "read", fnameindex);
594 | }
595 | lua_remove(L, fnameindex);
596 | return status;
597 | }
598 |
599 |
600 | COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) {
601 | int status = LUA_OK;
602 | if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
603 | status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
604 | }
605 | else {
606 | status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
607 | }
608 | if (status != LUA_OK)
609 | return status;
610 | return luaL_loadbuffer(L, buff, sz, name);
611 | }
612 |
613 |
614 | #if !defined(l_inspectstat) && \
615 | (defined(unix) || defined(__unix) || defined(__unix__) || \
616 | defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || \
617 | (defined(__APPLE__) && defined(__MACH__)))
618 | /* some form of unix; check feature macros in unistd.h for details */
619 | # include
620 | /* check posix version; the relevant include files and macros probably
621 | * were available before 2001, but I'm not sure */
622 | # if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
623 | # include
624 | # define l_inspectstat(stat,what) \
625 | if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
626 | else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
627 | # endif
628 | #endif
629 |
630 | /* provide default (no-op) version */
631 | #if !defined(l_inspectstat)
632 | # define l_inspectstat(stat,what) ((void)0)
633 | #endif
634 |
635 |
636 | COMPAT53_API int luaL_execresult (lua_State *L, int stat) {
637 | const char *what = "exit";
638 | if (stat == -1)
639 | return luaL_fileresult(L, 0, NULL);
640 | else {
641 | l_inspectstat(stat, what);
642 | if (*what == 'e' && stat == 0)
643 | lua_pushboolean(L, 1);
644 | else
645 | lua_pushnil(L);
646 | lua_pushstring(L, what);
647 | lua_pushinteger(L, stat);
648 | return 3;
649 | }
650 | }
651 |
652 |
653 | COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B) {
654 | /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
655 | B->b.p = NULL;
656 | B->b.L = NULL;
657 | B->b.lvl = 0;
658 | /* reuse the buffer from the 5.1-style luaL_Buffer though! */
659 | B->ptr = B->b.buffer;
660 | B->capacity = LUAL_BUFFERSIZE;
661 | B->nelems = 0;
662 | B->L2 = L;
663 | }
664 |
665 |
666 | COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s) {
667 | if (B->capacity - B->nelems < s) { /* needs to grow */
668 | char* newptr = NULL;
669 | size_t newcap = B->capacity * 2;
670 | if (newcap - B->nelems < s)
671 | newcap = B->nelems + s;
672 | if (newcap < B->capacity) /* overflow */
673 | luaL_error(B->L2, "buffer too large");
674 | newptr = (char*)lua_newuserdata(B->L2, newcap);
675 | memcpy(newptr, B->ptr, B->nelems);
676 | if (B->ptr != B->b.buffer)
677 | lua_replace(B->L2, -2); /* remove old buffer */
678 | B->ptr = newptr;
679 | B->capacity = newcap;
680 | }
681 | return B->ptr+B->nelems;
682 | }
683 |
684 |
685 | COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l) {
686 | memcpy(luaL_prepbuffsize(B, l), s, l);
687 | luaL_addsize(B, l);
688 | }
689 |
690 |
691 | COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B) {
692 | size_t len = 0;
693 | const char *s = lua_tolstring(B->L2, -1, &len);
694 | if (!s)
695 | luaL_error(B->L2, "cannot convert value to string");
696 | if (B->ptr != B->b.buffer)
697 | lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
698 | luaL_addlstring(B, s, len);
699 | lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
700 | }
701 |
702 |
703 | void luaL_pushresult (luaL_Buffer_53 *B) {
704 | lua_pushlstring(B->L2, B->ptr, B->nelems);
705 | if (B->ptr != B->b.buffer)
706 | lua_replace(B->L2, -2); /* remove userdata buffer */
707 | }
708 |
709 |
710 | #endif /* Lua 5.1 */
711 |
712 |
713 |
714 | /* definitions for Lua 5.1 and Lua 5.2 */
715 | #if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM <= 502
716 |
717 |
718 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i) {
719 | index = lua_absindex(L, index);
720 | lua_pushinteger(L, i);
721 | lua_gettable(L, index);
722 | return lua_type(L, -1);
723 | }
724 |
725 |
726 | #ifndef LUA_EXTRASPACE
727 | #define LUA_EXTRASPACE (sizeof(void*))
728 | #endif
729 |
730 | COMPAT53_API void *lua_getextraspace (lua_State *L) {
731 | int is_main = 0;
732 | void *ptr = NULL;
733 | luaL_checkstack(L, 4, "not enough stack slots available");
734 | lua_pushliteral(L, "__compat53_extraspace");
735 | lua_pushvalue(L, -1);
736 | lua_rawget(L, LUA_REGISTRYINDEX);
737 | if (!lua_istable(L, -1)) {
738 | lua_pop(L, 1);
739 | lua_createtable(L, 0, 2);
740 | lua_createtable(L, 0, 1);
741 | lua_pushliteral(L, "k");
742 | lua_setfield(L, -2, "__mode");
743 | lua_setmetatable(L, -2);
744 | lua_pushvalue(L, -2);
745 | lua_pushvalue(L, -2);
746 | lua_rawset(L, LUA_REGISTRYINDEX);
747 | }
748 | lua_replace(L, -2);
749 | is_main = lua_pushthread(L);
750 | lua_rawget(L, -2);
751 | ptr = lua_touserdata(L, -1);
752 | if (!ptr) {
753 | lua_pop(L, 1);
754 | ptr = lua_newuserdata(L, LUA_EXTRASPACE);
755 | if (is_main) {
756 | memset(ptr, '\0', LUA_EXTRASPACE);
757 | lua_pushthread(L);
758 | lua_pushvalue(L, -2);
759 | lua_rawset(L, -4);
760 | lua_pushboolean(L, 1);
761 | lua_pushvalue(L, -2);
762 | lua_rawset(L, -4);
763 | } else {
764 | void* mptr = NULL;
765 | lua_pushboolean(L, 1);
766 | lua_rawget(L, -3);
767 | mptr = lua_touserdata(L, -1);
768 | if (mptr)
769 | memcpy(ptr, mptr, LUA_EXTRASPACE);
770 | else
771 | memset(ptr, '\0', LUA_EXTRASPACE);
772 | lua_pop(L, 1);
773 | lua_pushthread(L);
774 | lua_pushvalue(L, -2);
775 | lua_rawset(L, -4);
776 | }
777 | }
778 | lua_pop(L, 2);
779 | return ptr;
780 | }
781 |
782 |
783 | COMPAT53_API int lua_isinteger (lua_State *L, int index) {
784 | if (lua_type(L, index) == LUA_TNUMBER) {
785 | lua_Number n = lua_tonumber(L, index);
786 | lua_Integer i = lua_tointeger(L, index);
787 | if (i == n)
788 | return 1;
789 | }
790 | return 0;
791 | }
792 |
793 |
794 | COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) {
795 | int ok = 0;
796 | lua_Number n = lua_tonumberx(L, i, &ok);
797 | if (ok) {
798 | if (n == (lua_Integer)n) {
799 | if (isnum)
800 | *isnum = 1;
801 | return (lua_Integer)n;
802 | }
803 | }
804 | if (isnum)
805 | *isnum = 0;
806 | return 0;
807 | }
808 |
809 |
810 | static void compat53_reverse (lua_State *L, int a, int b) {
811 | for (; a < b; ++a, --b) {
812 | lua_pushvalue(L, a);
813 | lua_pushvalue(L, b);
814 | lua_replace(L, a);
815 | lua_replace(L, b);
816 | }
817 | }
818 |
819 |
820 | COMPAT53_API void lua_rotate (lua_State *L, int idx, int n) {
821 | int n_elems = 0;
822 | idx = lua_absindex(L, idx);
823 | n_elems = lua_gettop(L)-idx+1;
824 | if (n < 0)
825 | n += n_elems;
826 | if ( n > 0 && n < n_elems) {
827 | luaL_checkstack(L, 2, "not enough stack slots available");
828 | n = n_elems - n;
829 | compat53_reverse(L, idx, idx+n-1);
830 | compat53_reverse(L, idx+n, idx+n_elems-1);
831 | compat53_reverse(L, idx, idx+n_elems-1);
832 | }
833 | }
834 |
835 |
836 | COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i) {
837 | luaL_checkstack(L, 1, "not enough stack slots available");
838 | index = lua_absindex(L, index);
839 | lua_pushinteger(L, i);
840 | lua_insert(L, -2);
841 | lua_settable(L, index);
842 | }
843 |
844 |
845 | #if !defined(lua_str2number)
846 | # define lua_str2number(s, p) strtod((s), (p))
847 | #endif
848 |
849 | COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s) {
850 | char* endptr;
851 | lua_Number n = lua_str2number(s, &endptr);
852 | if (endptr != s) {
853 | while (*endptr != '\0' && isspace((unsigned char)*endptr))
854 | ++endptr;
855 | if (*endptr == '\0') {
856 | lua_pushnumber(L, n);
857 | return endptr - s + 1;
858 | }
859 | }
860 | return 0;
861 | }
862 |
863 |
864 | COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
865 | if (!luaL_callmeta(L, idx, "__tostring")) {
866 | int t = lua_type(L, idx), tt = 0;
867 | char const* name = NULL;
868 | switch (t) {
869 | case LUA_TNIL:
870 | lua_pushliteral(L, "nil");
871 | break;
872 | case LUA_TSTRING:
873 | case LUA_TNUMBER:
874 | lua_pushvalue(L, idx);
875 | break;
876 | case LUA_TBOOLEAN:
877 | if (lua_toboolean(L, idx))
878 | lua_pushliteral(L, "true");
879 | else
880 | lua_pushliteral(L, "false");
881 | break;
882 | default:
883 | tt = luaL_getmetafield(L, idx, "__name");
884 | name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t);
885 | lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx));
886 | if (tt != LUA_TNIL)
887 | lua_replace(L, -2);
888 | break;
889 | }
890 | } else {
891 | if (!lua_isstring(L, -1))
892 | luaL_error(L, "'__tostring' must return a string");
893 | }
894 | return lua_tolstring(L, -1, len);
895 | }
896 |
897 |
898 | COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
899 | lua_CFunction openf, int glb) {
900 | luaL_checkstack(L, 3, "not enough stack slots available");
901 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
902 | if (lua_getfield(L, -1, modname) == LUA_TNIL) {
903 | lua_pop(L, 1);
904 | lua_pushcfunction(L, openf);
905 | lua_pushstring(L, modname);
906 | lua_call(L, 1, 1);
907 | lua_pushvalue(L, -1);
908 | lua_setfield(L, -3, modname);
909 | }
910 | if (glb) {
911 | lua_pushvalue(L, -1);
912 | lua_setglobal(L, modname);
913 | }
914 | lua_replace(L, -2);
915 | }
916 |
917 |
918 | #endif /* Lua 5.1 and 5.2 */
919 |
920 |
921 | #endif /* COMPAT53_C_ */
922 |
923 |
924 | /*********************************************************************
925 | * This file contains parts of Lua 5.2's and Lua 5.3's source code:
926 | *
927 | * Copyright (C) 1994-2014 Lua.org, PUC-Rio.
928 | *
929 | * Permission is hereby granted, free of charge, to any person obtaining
930 | * a copy of this software and associated documentation files (the
931 | * "Software"), to deal in the Software without restriction, including
932 | * without limitation the rights to use, copy, modify, merge, publish,
933 | * distribute, sublicense, and/or sell copies of the Software, and to
934 | * permit persons to whom the Software is furnished to do so, subject to
935 | * the following conditions:
936 | *
937 | * The above copyright notice and this permission notice shall be
938 | * included in all copies or substantial portions of the Software.
939 | *
940 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
941 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
942 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
943 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
944 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
945 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
946 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
947 | *********************************************************************/
948 |
949 |
--------------------------------------------------------------------------------
/src/compat-5.3.h:
--------------------------------------------------------------------------------
1 | #ifndef COMPAT53_H_
2 | #define COMPAT53_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
8 | extern "C" {
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
14 | }
15 | #endif
16 |
17 |
18 | #undef COMPAT53_INCLUDE_SOURCE
19 | #if defined(COMPAT53_PREFIX)
20 | /* - change the symbol names of functions to avoid linker conflicts
21 | * - compat-5.3.c needs to be compiled (and linked) separately
22 | */
23 | # if !defined(COMPAT53_API)
24 | # define COMPAT53_API extern
25 | # endif
26 | #else /* COMPAT53_PREFIX */
27 | /* - make all functions static and include the source.
28 | * - compat-5.3.c doesn't need to be compiled (and linked) separately
29 | */
30 | # define COMPAT53_PREFIX compat53
31 | # undef COMPAT53_API
32 | # if defined(__GNUC__) || defined(__clang__)
33 | # define COMPAT53_API __attribute__((__unused__)) static
34 | # else
35 | # define COMPAT53_API static
36 | # endif
37 | # define COMPAT53_INCLUDE_SOURCE
38 | #endif /* COMPAT53_PREFIX */
39 |
40 | #define COMPAT53_CONCAT_HELPER(a, b) a##b
41 | #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
42 |
43 |
44 |
45 | /* declarations for Lua 5.1 */
46 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
47 |
48 | /* XXX not implemented:
49 | * lua_arith (new operators)
50 | * lua_upvalueid
51 | * lua_upvaluejoin
52 | * lua_version
53 | * lua_yieldk
54 | */
55 |
56 | #ifndef LUA_OK
57 | # define LUA_OK 0
58 | #endif
59 | #ifndef LUA_OPADD
60 | # define LUA_OPADD 0
61 | #endif
62 | #ifndef LUA_OPSUB
63 | # define LUA_OPSUB 1
64 | #endif
65 | #ifndef LUA_OPMUL
66 | # define LUA_OPMUL 2
67 | #endif
68 | #ifndef LUA_OPDIV
69 | # define LUA_OPDIV 3
70 | #endif
71 | #ifndef LUA_OPMOD
72 | # define LUA_OPMOD 4
73 | #endif
74 | #ifndef LUA_OPPOW
75 | # define LUA_OPPOW 5
76 | #endif
77 | #ifndef LUA_OPUNM
78 | # define LUA_OPUNM 6
79 | #endif
80 | #ifndef LUA_OPEQ
81 | # define LUA_OPEQ 0
82 | #endif
83 | #ifndef LUA_OPLT
84 | # define LUA_OPLT 1
85 | #endif
86 | #ifndef LUA_OPLE
87 | # define LUA_OPLE 2
88 | #endif
89 |
90 | /* LuaJIT/Lua 5.1 does not have the updated
91 | * error codes for thread status/function returns (but some patched versions do)
92 | * define it only if it's not found
93 | */
94 | #if !defined(LUA_ERRGCMM)
95 | /* Use + 2 because in some versions of Lua (Lua 5.1)
96 | * LUA_ERRFILE is defined as (LUA_ERRERR+1)
97 | * so we need to avoid it (LuaJIT might have something at this
98 | * integer value too)
99 | */
100 | # define LUA_ERRGCMM (LUA_ERRERR + 2)
101 | #endif /* LUA_ERRGCMM define */
102 |
103 | typedef size_t lua_Unsigned;
104 |
105 | typedef struct luaL_Buffer_53 {
106 | luaL_Buffer b; /* make incorrect code crash! */
107 | char *ptr;
108 | size_t nelems;
109 | size_t capacity;
110 | lua_State *L2;
111 | } luaL_Buffer_53;
112 | #define luaL_Buffer luaL_Buffer_53
113 |
114 | /* In PUC-Rio 5.1, userdata is a simple FILE*
115 | * In LuaJIT, it's a struct where the first member is a FILE*
116 | * We can't support the `closef` member
117 | */
118 | typedef struct luaL_Stream {
119 | FILE *f;
120 | } luaL_Stream;
121 |
122 | #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
123 | COMPAT53_API int lua_absindex (lua_State *L, int i);
124 |
125 | #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
126 | COMPAT53_API void lua_arith (lua_State *L, int op);
127 |
128 | #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
129 | COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op);
130 |
131 | #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
132 | COMPAT53_API void lua_copy (lua_State *L, int from, int to);
133 |
134 | #define lua_getuservalue(L, i) \
135 | (lua_getfenv((L), (i)), lua_type((L), -1))
136 | #define lua_setuservalue(L, i) \
137 | (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
138 |
139 | #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
140 | COMPAT53_API void lua_len (lua_State *L, int i);
141 |
142 | #define lua_pushstring(L, s) \
143 | (lua_pushstring((L), (s)), lua_tostring((L), -1))
144 |
145 | #define lua_pushlstring(L, s, len) \
146 | ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
147 |
148 | #ifndef luaL_newlibtable
149 | # define luaL_newlibtable(L, l) \
150 | (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
151 | #endif
152 | #ifndef luaL_newlib
153 | # define luaL_newlib(L, l) \
154 | (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
155 | #endif
156 |
157 | #define lua_pushglobaltable(L) \
158 | lua_pushvalue((L), LUA_GLOBALSINDEX)
159 |
160 | #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
161 | COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p);
162 |
163 | #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
164 | COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
165 |
166 | #define lua_rawlen(L, i) lua_objlen((L), (i))
167 |
168 | #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
169 |
170 | #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
171 | COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum);
172 |
173 | #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
174 | COMPAT53_API void luaL_checkversion (lua_State *L);
175 |
176 | #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
177 | COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
178 |
179 | #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
180 | COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode);
181 |
182 | #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
183 | COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
184 |
185 | #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
186 | COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg);
187 |
188 | #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
189 | COMPAT53_API int luaL_getsubtable (lua_State* L, int i, const char *name);
190 |
191 | #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
192 | COMPAT53_API lua_Integer luaL_len (lua_State *L, int i);
193 |
194 | #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
195 | COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
196 |
197 | #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
198 | COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname);
199 |
200 | #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
201 | COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname);
202 |
203 | #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
204 | COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level);
205 |
206 | #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
207 | COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname);
208 |
209 | #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
210 | COMPAT53_API int luaL_execresult (lua_State *L, int stat);
211 |
212 | #define lua_callk(L, na, nr, ctx, cont) \
213 | ((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
214 | #define lua_pcallk(L, na, nr, err, ctx, cont) \
215 | ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
216 |
217 | #define lua_resume(L, from, nargs) \
218 | ((void)(from), lua_resume((L), (nargs)))
219 |
220 | #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
221 | COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B);
222 |
223 | #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
224 | COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s);
225 |
226 | #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
227 | COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l);
228 |
229 | #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
230 | COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B);
231 |
232 | #define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
233 | COMPAT53_API void luaL_pushresult (luaL_Buffer_53 *B);
234 |
235 | #undef luaL_buffinitsize
236 | #define luaL_buffinitsize(L, B, s) \
237 | (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
238 |
239 | #undef luaL_prepbuffer
240 | #define luaL_prepbuffer(B) \
241 | luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
242 |
243 | #undef luaL_addchar
244 | #define luaL_addchar(B, c) \
245 | ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
246 | ((B)->ptr[(B)->nelems++] = (c)))
247 |
248 | #undef luaL_addsize
249 | #define luaL_addsize(B, s) \
250 | ((B)->nelems += (s))
251 |
252 | #undef luaL_addstring
253 | #define luaL_addstring(B, s) \
254 | luaL_addlstring((B), (s), strlen((s)))
255 |
256 | #undef luaL_pushresultsize
257 | #define luaL_pushresultsize(B, s) \
258 | (luaL_addsize((B), (s)), luaL_pushresult((B)))
259 |
260 | #if defined(LUA_COMPAT_APIINTCASTS)
261 | #define lua_pushunsigned(L, n) \
262 | lua_pushinteger((L), (lua_Integer)(n))
263 | #define lua_tounsignedx(L, i, is) \
264 | ((lua_Unsigned)lua_tointegerx((L), (i), (is)))
265 | #define lua_tounsigned(L, i) \
266 | lua_tounsignedx((L), (i), NULL)
267 | #define luaL_checkunsigned(L, a) \
268 | ((lua_Unsigned)luaL_checkinteger((L), (a)))
269 | #define luaL_optunsigned(L, a, d) \
270 | ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
271 | #endif
272 |
273 | #endif /* Lua 5.1 only */
274 |
275 |
276 |
277 | /* declarations for Lua 5.1 and 5.2 */
278 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
279 |
280 | typedef int lua_KContext;
281 |
282 | typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
283 |
284 | #define lua_dump(L, w, d, s) \
285 | ((void)(s), lua_dump((L), (w), (d)))
286 |
287 | #define lua_getfield(L, i, k) \
288 | (lua_getfield((L), (i), (k)), lua_type((L), -1))
289 |
290 | #define lua_gettable(L, i) \
291 | (lua_gettable((L), (i)), lua_type((L), -1))
292 |
293 | #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
294 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i);
295 |
296 | #define lua_getextraspace COMPAT53_CONCAT(COMPAT53_PREFIX, _getextraspace)
297 | COMPAT53_API void *lua_getextraspace (lua_State *L);
298 |
299 | #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
300 | COMPAT53_API int lua_isinteger (lua_State *L, int index);
301 |
302 | #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
303 | COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum);
304 |
305 | #define lua_numbertointeger(n, p) \
306 | ((*(p) = (lua_Integer)(n)), 1)
307 |
308 | #define lua_rawget(L, i) \
309 | (lua_rawget((L), (i)), lua_type((L), -1))
310 |
311 | #define lua_rawgeti(L, i, n) \
312 | (lua_rawgeti((L), (i), (n)), lua_type((L), -1))
313 |
314 | #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
315 | COMPAT53_API void lua_rotate (lua_State *L, int idx, int n);
316 |
317 | #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
318 | COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i);
319 |
320 | #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
321 | COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s);
322 |
323 | #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
324 | COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
325 |
326 | #define luaL_getmetafield(L, o, e) \
327 | (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
328 |
329 | #define luaL_newmetatable(L, tn) \
330 | (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
331 |
332 | #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
333 | COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
334 | lua_CFunction openf, int glb );
335 |
336 | #endif /* Lua 5.1 and Lua 5.2 */
337 |
338 |
339 |
340 | /* declarations for Lua 5.2 */
341 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
342 |
343 | /* XXX not implemented:
344 | * lua_isyieldable
345 | * lua_arith (new operators)
346 | * lua_pushfstring (new formats)
347 | */
348 |
349 | #define lua_getglobal(L, n) \
350 | (lua_getglobal((L), (n)), lua_type((L), -1))
351 |
352 | #define lua_getuservalue(L, i) \
353 | (lua_getuservalue((L), (i)), lua_type((L), -1))
354 |
355 | #define lua_pushlstring(L, s, len) \
356 | (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
357 |
358 | #define lua_rawgetp(L, i, p) \
359 | (lua_rawgetp((L), (i), (p)), lua_type((L), -1))
360 |
361 | #define LUA_KFUNCTION(_name) \
362 | static int (_name)(lua_State *L, int status, lua_KContext ctx); \
363 | static int (_name ## _52)(lua_State *L) { \
364 | lua_KContext ctx; \
365 | int status = lua_getctx(L, &ctx); \
366 | return (_name)(L, status, ctx); \
367 | } \
368 | static int (_name)(lua_State *L, int status, lua_KContext ctx)
369 |
370 | #define lua_pcallk(L, na, nr, err, ctx, cont) \
371 | lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
372 |
373 | #define lua_callk(L, na, nr, ctx, cont) \
374 | lua_callk((L), (na), (nr), (ctx), cont ## _52)
375 |
376 | #define lua_yieldk(L, nr, ctx, cont) \
377 | lua_yieldk((L), (nr), (ctx), cont ## _52)
378 |
379 | #ifdef lua_call
380 | # undef lua_call
381 | # define lua_call(L, na, nr) \
382 | (lua_callk)((L), (na), (nr), 0, NULL)
383 | #endif
384 |
385 | #ifdef lua_pcall
386 | # undef lua_pcall
387 | # define lua_pcall(L, na, nr, err) \
388 | (lua_pcallk)((L), (na), (nr), (err), 0, NULL)
389 | #endif
390 |
391 | #ifdef lua_yield
392 | # undef lua_yield
393 | # define lua_yield(L, nr) \
394 | (lua_yieldk)((L), (nr), 0, NULL)
395 | #endif
396 |
397 | #endif /* Lua 5.2 only */
398 |
399 |
400 |
401 | /* other Lua versions */
402 | #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
403 | //@@ #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 503
404 |
405 | # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, or 5.3)"
406 |
407 | #endif /* other Lua versions except 5.1, 5.2, and 5.3 */
408 |
409 |
410 |
411 | /* helper macro for defining continuation functions (for every version
412 | * *except* Lua 5.2) */
413 | #ifndef LUA_KFUNCTION
414 | #define LUA_KFUNCTION(_name) \
415 | static int (_name)(lua_State *L, int status, lua_KContext ctx)
416 | #endif
417 |
418 |
419 | #if defined(COMPAT53_INCLUDE_SOURCE)
420 | # include "compat-5.3.c"
421 | #endif
422 |
423 |
424 | #endif /* COMPAT53_H_ */
425 |
426 |
--------------------------------------------------------------------------------
/src/include/stb_perlin.h:
--------------------------------------------------------------------------------
1 | // stb_perlin.h - v0.5 - perlin noise
2 | // public domain single-file C implementation by Sean Barrett
3 | //
4 | // LICENSE
5 | //
6 | // See end of file.
7 | //
8 | //
9 | // to create the implementation,
10 | // #define STB_PERLIN_IMPLEMENTATION
11 | // in *one* C/CPP file that includes this file.
12 | //
13 | //
14 | // Documentation:
15 | //
16 | // float stb_perlin_noise3( float x,
17 | // float y,
18 | // float z,
19 | // int x_wrap=0,
20 | // int y_wrap=0,
21 | // int z_wrap=0)
22 | //
23 | // This function computes a random value at the coordinate (x,y,z).
24 | // Adjacent random values are continuous but the noise fluctuates
25 | // its randomness with period 1, i.e. takes on wholly unrelated values
26 | // at integer points. Specifically, this implements Ken Perlin's
27 | // revised noise function from 2002.
28 | //
29 | // The "wrap" parameters can be used to create wraparound noise that
30 | // wraps at powers of two. The numbers MUST be powers of two. Specify
31 | // 0 to mean "don't care". (The noise always wraps every 256 due
32 | // details of the implementation, even if you ask for larger or no
33 | // wrapping.)
34 | //
35 | // float stb_perlin_noise3_seed( float x,
36 | // float y,
37 | // float z,
38 | // int x_wrap=0,
39 | // int y_wrap=0,
40 | // int z_wrap=0,
41 | // int seed)
42 | //
43 | // As above, but 'seed' selects from multiple different variations of the
44 | // noise function. The current implementation only uses the bottom 8 bits
45 | // of 'seed', but possibly in the future more bits will be used.
46 | //
47 | //
48 | // Fractal Noise:
49 | //
50 | // Three common fractal noise functions are included, which produce
51 | // a wide variety of nice effects depending on the parameters
52 | // provided. Note that each function will call stb_perlin_noise3
53 | // 'octaves' times, so this parameter will affect runtime.
54 | //
55 | // float stb_perlin_ridge_noise3(float x, float y, float z,
56 | // float lacunarity, float gain, float offset, int octaves)
57 | //
58 | // float stb_perlin_fbm_noise3(float x, float y, float z,
59 | // float lacunarity, float gain, int octaves)
60 | //
61 | // float stb_perlin_turbulence_noise3(float x, float y, float z,
62 | // float lacunarity, float gain, int octaves)
63 | //
64 | // Typical values to start playing with:
65 | // octaves = 6 -- number of "octaves" of noise3() to sum
66 | // lacunarity = ~ 2.0 -- spacing between successive octaves (use exactly 2.0 for wrapping output)
67 | // gain = 0.5 -- relative weighting applied to each successive octave
68 | // offset = 1.0? -- used to invert the ridges, may need to be larger, not sure
69 | //
70 | //
71 | // Contributors:
72 | // Jack Mott - additional noise functions
73 | // Jordan Peck - seeded noise
74 | //
75 |
76 |
77 | #ifdef __cplusplus
78 | extern "C" {
79 | #endif
80 | extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
81 | extern float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed);
82 | extern float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
83 | extern float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
84 | extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
85 | extern float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
86 | #ifdef __cplusplus
87 | }
88 | #endif
89 |
90 | #ifdef STB_PERLIN_IMPLEMENTATION
91 |
92 | #include // fabs()
93 |
94 | // not same permutation table as Perlin's reference to avoid copyright issues;
95 | // Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
96 | static unsigned char stb__perlin_randtab[512] =
97 | {
98 | 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
99 | 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
100 | 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
101 | 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
102 | 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
103 | 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
104 | 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
105 | 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
106 | 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
107 | 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
108 | 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
109 | 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
110 | 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
111 | 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
112 | 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
113 | 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
114 |
115 | // and a second copy so we don't need an extra mask or static initializer
116 | 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
117 | 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
118 | 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
119 | 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
120 | 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
121 | 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
122 | 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
123 | 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
124 | 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
125 | 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
126 | 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
127 | 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
128 | 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
129 | 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
130 | 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
131 | 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
132 | };
133 |
134 |
135 | // perlin's gradient has 12 cases so some get used 1/16th of the time
136 | // and some 2/16ths. We reduce bias by changing those fractions
137 | // to 5/64ths and 6/64ths
138 |
139 | // this array is designed to match the previous implementation
140 | // of gradient hash: indices[stb__perlin_randtab[i]&63]
141 | static unsigned char stb__perlin_randtab_grad_idx[512] =
142 | {
143 | 7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
144 | 8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
145 | 7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
146 | 8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
147 | 5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
148 | 2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
149 | 9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
150 | 1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
151 | 10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
152 | 6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
153 | 4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
154 | 11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
155 | 10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
156 | 3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
157 | 11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
158 | 9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
159 |
160 | // and a second copy so we don't need an extra mask or static initializer
161 | 7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
162 | 8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
163 | 7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
164 | 8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
165 | 5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
166 | 2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
167 | 9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
168 | 1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
169 | 10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
170 | 6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
171 | 4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
172 | 11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
173 | 10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
174 | 3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
175 | 11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
176 | 9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
177 | };
178 |
179 | static float stb__perlin_lerp(float a, float b, float t)
180 | {
181 | return a + (b-a) * t;
182 | }
183 |
184 | static int stb__perlin_fastfloor(float a)
185 | {
186 | int ai = (int) a;
187 | return (a < ai) ? ai-1 : ai;
188 | }
189 |
190 | // different grad function from Perlin's, but easy to modify to match reference
191 | static float stb__perlin_grad(int grad_idx, float x, float y, float z)
192 | {
193 | static float basis[12][4] =
194 | {
195 | { 1, 1, 0 },
196 | { -1, 1, 0 },
197 | { 1,-1, 0 },
198 | { -1,-1, 0 },
199 | { 1, 0, 1 },
200 | { -1, 0, 1 },
201 | { 1, 0,-1 },
202 | { -1, 0,-1 },
203 | { 0, 1, 1 },
204 | { 0,-1, 1 },
205 | { 0, 1,-1 },
206 | { 0,-1,-1 },
207 | };
208 |
209 | float *grad = basis[grad_idx];
210 | return grad[0]*x + grad[1]*y + grad[2]*z;
211 | }
212 |
213 | float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
214 | {
215 | float u,v,w;
216 | float n000,n001,n010,n011,n100,n101,n110,n111;
217 | float n00,n01,n10,n11;
218 | float n0,n1;
219 |
220 | unsigned int x_mask = (x_wrap-1) & 255;
221 | unsigned int y_mask = (y_wrap-1) & 255;
222 | unsigned int z_mask = (z_wrap-1) & 255;
223 | int px = stb__perlin_fastfloor(x);
224 | int py = stb__perlin_fastfloor(y);
225 | int pz = stb__perlin_fastfloor(z);
226 | int x0 = px & x_mask, x1 = (px+1) & x_mask;
227 | int y0 = py & y_mask, y1 = (py+1) & y_mask;
228 | int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
229 | int r0,r1, r00,r01,r10,r11;
230 |
231 | #define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
232 |
233 | x -= px; u = stb__perlin_ease(x);
234 | y -= py; v = stb__perlin_ease(y);
235 | z -= pz; w = stb__perlin_ease(z);
236 |
237 | r0 = stb__perlin_randtab[x0+seed];
238 | r1 = stb__perlin_randtab[x1+seed];
239 |
240 | r00 = stb__perlin_randtab[r0+y0];
241 | r01 = stb__perlin_randtab[r0+y1];
242 | r10 = stb__perlin_randtab[r1+y0];
243 | r11 = stb__perlin_randtab[r1+y1];
244 |
245 | n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
246 | n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
247 | n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
248 | n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
249 | n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
250 | n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
251 | n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
252 | n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
253 |
254 | n00 = stb__perlin_lerp(n000,n001,w);
255 | n01 = stb__perlin_lerp(n010,n011,w);
256 | n10 = stb__perlin_lerp(n100,n101,w);
257 | n11 = stb__perlin_lerp(n110,n111,w);
258 |
259 | n0 = stb__perlin_lerp(n00,n01,v);
260 | n1 = stb__perlin_lerp(n10,n11,v);
261 |
262 | return stb__perlin_lerp(n0,n1,u);
263 | }
264 |
265 | float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
266 | {
267 | return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap,0);
268 | }
269 |
270 | float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed)
271 | {
272 | return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap, (unsigned char) seed);
273 | }
274 |
275 | float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves)
276 | {
277 | int i;
278 | float frequency = 1.0f;
279 | float prev = 1.0f;
280 | float amplitude = 0.5f;
281 | float sum = 0.0f;
282 |
283 | for (i = 0; i < octaves; i++) {
284 | float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i);
285 | r = offset - (float) fabs(r);
286 | r = r*r;
287 | sum += r*amplitude*prev;
288 | prev = r;
289 | frequency *= lacunarity;
290 | amplitude *= gain;
291 | }
292 | return sum;
293 | }
294 |
295 | float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
296 | {
297 | int i;
298 | float frequency = 1.0f;
299 | float amplitude = 1.0f;
300 | float sum = 0.0f;
301 |
302 | for (i = 0; i < octaves; i++) {
303 | sum += stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
304 | frequency *= lacunarity;
305 | amplitude *= gain;
306 | }
307 | return sum;
308 | }
309 |
310 | float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
311 | {
312 | int i;
313 | float frequency = 1.0f;
314 | float amplitude = 1.0f;
315 | float sum = 0.0f;
316 |
317 | for (i = 0; i < octaves; i++) {
318 | float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
319 | sum += (float) fabs(r);
320 | frequency *= lacunarity;
321 | amplitude *= gain;
322 | }
323 | return sum;
324 | }
325 |
326 | float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
327 | {
328 | float u,v,w;
329 | float n000,n001,n010,n011,n100,n101,n110,n111;
330 | float n00,n01,n10,n11;
331 | float n0,n1;
332 |
333 | int px = stb__perlin_fastfloor(x);
334 | int py = stb__perlin_fastfloor(y);
335 | int pz = stb__perlin_fastfloor(z);
336 | int x_wrap2 = (x_wrap ? x_wrap : 256);
337 | int y_wrap2 = (y_wrap ? y_wrap : 256);
338 | int z_wrap2 = (z_wrap ? z_wrap : 256);
339 | int x0 = px % x_wrap2, x1;
340 | int y0 = py % y_wrap2, y1;
341 | int z0 = pz % z_wrap2, z1;
342 | int r0,r1, r00,r01,r10,r11;
343 |
344 | if (x0 < 0) x0 += x_wrap2;
345 | if (y0 < 0) y0 += y_wrap2;
346 | if (z0 < 0) z0 += z_wrap2;
347 | x1 = (x0+1) % x_wrap2;
348 | y1 = (y0+1) % y_wrap2;
349 | z1 = (z0+1) % z_wrap2;
350 |
351 | #define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
352 |
353 | x -= px; u = stb__perlin_ease(x);
354 | y -= py; v = stb__perlin_ease(y);
355 | z -= pz; w = stb__perlin_ease(z);
356 |
357 | r0 = stb__perlin_randtab[x0];
358 | r0 = stb__perlin_randtab[r0+seed];
359 | r1 = stb__perlin_randtab[x1];
360 | r1 = stb__perlin_randtab[r1+seed];
361 |
362 | r00 = stb__perlin_randtab[r0+y0];
363 | r01 = stb__perlin_randtab[r0+y1];
364 | r10 = stb__perlin_randtab[r1+y0];
365 | r11 = stb__perlin_randtab[r1+y1];
366 |
367 | n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
368 | n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
369 | n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
370 | n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
371 | n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
372 | n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
373 | n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
374 | n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
375 |
376 | n00 = stb__perlin_lerp(n000,n001,w);
377 | n01 = stb__perlin_lerp(n010,n011,w);
378 | n10 = stb__perlin_lerp(n100,n101,w);
379 | n11 = stb__perlin_lerp(n110,n111,w);
380 |
381 | n0 = stb__perlin_lerp(n00,n01,v);
382 | n1 = stb__perlin_lerp(n10,n11,v);
383 |
384 | return stb__perlin_lerp(n0,n1,u);
385 | }
386 | #endif // STB_PERLIN_IMPLEMENTATION
387 |
388 | /*
389 | ------------------------------------------------------------------------------
390 | This software is available under 2 licenses -- choose whichever you prefer.
391 | ------------------------------------------------------------------------------
392 | ALTERNATIVE A - MIT License
393 | Copyright (c) 2017 Sean Barrett
394 | Permission is hereby granted, free of charge, to any person obtaining a copy of
395 | this software and associated documentation files (the "Software"), to deal in
396 | the Software without restriction, including without limitation the rights to
397 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
398 | of the Software, and to permit persons to whom the Software is furnished to do
399 | so, subject to the following conditions:
400 | The above copyright notice and this permission notice shall be included in all
401 | copies or substantial portions of the Software.
402 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
403 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
404 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
405 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
406 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
407 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
408 | SOFTWARE.
409 | ------------------------------------------------------------------------------
410 | ALTERNATIVE B - Public Domain (www.unlicense.org)
411 | This is free and unencumbered software released into the public domain.
412 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
413 | software, either in source code form or as a compiled binary, for any purpose,
414 | commercial or non-commercial, and by any means.
415 | In jurisdictions that recognize copyright laws, the author or authors of this
416 | software dedicate any and all copyright interest in the software to the public
417 | domain. We make this dedication for the benefit of the public at large and to
418 | the detriment of our heirs and successors. We intend this dedication to be an
419 | overt act of relinquishment in perpetuity of all present and future rights to
420 | this software under copyright law.
421 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
422 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
423 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
424 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
425 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
426 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
427 | ------------------------------------------------------------------------------
428 | */
429 |
--------------------------------------------------------------------------------
/src/internal.h:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | /********************************************************************************
27 | * Internal common header *
28 | ********************************************************************************/
29 |
30 | #ifndef internalDEFINED
31 | #define internalDEFINED
32 |
33 | #include
34 | #include
35 | #include
36 | #include "moonimage.h"
37 |
38 | #define TOSTR_(x) #x
39 | #define TOSTR(x) TOSTR_(x)
40 |
41 | /* Note: all the dynamic symbols of this library (should) start with 'moonimage_' .
42 | * The only exception is the luaopen_moonimage() function, which is searched for
43 | * with that name by Lua.
44 | * MoonImage's string references on the Lua registry also start with 'moonimage_'.
45 | */
46 |
47 | #if 0
48 | /* .c */
49 | #define moonimage_
50 | #endif
51 |
52 | /* utils.c */
53 | #define noprintf moonimage_noprintf
54 | int noprintf(const char *fmt, ...);
55 | #define notavailable moonimage_notavailable
56 | int notavailable(lua_State *L, ...);
57 | #define malloc_init moonimage_malloc_init
58 | void malloc_init(lua_State *L);
59 | #define Malloc moonimage_Malloc
60 | void *Malloc(lua_State *L, size_t size);
61 | #define MallocNoErr moonimage_MallocNoErr
62 | void *MallocNoErr(lua_State *L, size_t size);
63 | #define Strdup moonimage_Strdup
64 | char *Strdup(lua_State *L, const char *s);
65 | #define Free moonimage_Free
66 | void Free(lua_State *L, void *ptr);
67 | #define checkboolean moonimage_checkboolean
68 | int checkboolean(lua_State *L, int arg);
69 | #define testboolean moonimage_testboolean
70 | int testboolean(lua_State *L, int arg, int *err);
71 | #define optboolean moonimage_optboolean
72 | int optboolean(lua_State *L, int arg, int d);
73 |
74 | #define checkchannels moonimage_checkchannels
75 | int checkchannels(lua_State *L, int arg);
76 | #define optchannels moonimage_optchannels
77 | int optchannels(lua_State *L, int arg);
78 | #define pushchannels moonimage_pushchannels
79 | int pushchannels(lua_State *L, int val);
80 | #define checkchantype moonimage_checkchantype
81 | int checkchantype(lua_State *L, int arg);
82 | #define optchantype moonimage_optchantype
83 | int optchantype(lua_State *L, int arg, int defval);
84 | #define pushchantype moonimage_pushchantype
85 | int pushchantype(lua_State *L, int val);
86 |
87 | #define checkflags(L, arg) (uint32_t)luaL_checkinteger((L), (arg))
88 | #define optflags(L, arg, defval) (uint32_t)luaL_optinteger((L), (arg), (defval))
89 |
90 |
91 | /* Color channels.
92 | * Note that the length of the corresponding Lua literal gives the number of channels
93 | * (y = 1, ya = 2, rgb = 3, rgba = 4).
94 | */
95 | #define CHAN_default 0 /* STBI_default */
96 | #define CHAN_y 1 /* STBI_grey */
97 | #define CHAN_ya 2 /* STBI_grey_alpha */
98 | #define CHAN_rgb 3 /* STBI_rgb */
99 | #define CHAN_rgba 4 /* STBI_rgb_alpha */
100 |
101 | /* Color channel type. */
102 | #define CHANTYPE_u8 0
103 | #define CHANTYPE_u16 1
104 | #define CHANTYPE_f 2
105 | /* Internal error codes */
106 | #define ERR_NOTPRESENT 1
107 | #define ERR_SUCCESS 0
108 | #define ERR_GENERIC -1
109 | #define ERR_TYPE -2
110 | #define ERR_VALUE -3
111 | #define ERR_TABLE -4
112 | #define ERR_EMPTY -5
113 | #define ERR_MEMORY -6
114 | #define ERR_LENGTH -7
115 | #define ERR_POOL -8
116 | #define ERR_BOUNDARIES -9
117 | #define ERR_UNKNOWN -10
118 | #define errstring moonimage_errstring
119 | const char* errstring(int err);
120 |
121 | /* main.c */
122 | int luaopen_moonimage(lua_State *L);
123 | void moonimage_open_load(lua_State *L);
124 | void moonimage_open_write(lua_State *L);
125 | void moonimage_open_perlin(lua_State *L);
126 |
127 | /*------------------------------------------------------------------------------*
128 | | Debug and other utilities |
129 | *------------------------------------------------------------------------------*/
130 |
131 | /* If this is printed, it denotes a suspect bug: */
132 | #define UNEXPECTED_ERROR "unexpected error (%s, %d)", __FILE__, __LINE__
133 |
134 | #define unexpected(L) luaL_error((L), UNEXPECTED_ERROR)
135 | #define notsupported(L) luaL_error((L), "operation not supported")
136 |
137 | #define badvalue(L,s) lua_pushfstring((L), "invalid value '%s'", (s))
138 |
139 | /* DEBUG -------------------------------------------------------- */
140 | #if defined(DEBUG)
141 |
142 | #define DBG printf
143 | #define TR() do { printf("trace %s %d\n",__FILE__,__LINE__); } while(0)
144 | #define BK() do { printf("break %s %d\n",__FILE__,__LINE__); getchar(); } while(0)
145 |
146 | #else
147 |
148 | #define DBG noprintf
149 | #define TR()
150 | #define BK()
151 |
152 | #endif /* DEBUG ------------------------------------------------- */
153 |
154 |
155 | #endif /* internalDEFINED */
156 |
--------------------------------------------------------------------------------
/src/load.c:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | #include "internal.h"
27 | #define STB_IMAGE_IMPLEMENTATION
28 | #define STBI_FAILURE_USERMSG
29 | #define STB_IMAGE_STATIC
30 | #include "stb_image.h"
31 |
32 | static int Error(lua_State *L)
33 | {
34 | const char * reason = stbi_failure_reason(); /* a VERY brief reason for failure */
35 | return luaL_error(L, (reason!=NULL) ? reason : "unknown reason");
36 | }
37 |
38 | /* FLAGS --------------------------------------------------------------------*/
39 |
40 | static int Reset_load_flags(lua_State *L)
41 | {
42 | (void)L;
43 | stbi_set_unpremultiply_on_load(0);
44 | stbi_convert_iphone_png_to_rgb(0);
45 | stbi_set_flip_vertically_on_load(0);
46 | return 0;
47 | }
48 |
49 | #define SET_FLAG_FUNC(Func, func) \
50 | static int Func(lua_State *L) \
51 | { \
52 | stbi_##func(checkboolean(L, 1)); \
53 | return 0; \
54 | }
55 |
56 | SET_FLAG_FUNC(Set_unpremultiply_on_load, set_unpremultiply_on_load)
57 | SET_FLAG_FUNC(Convert_iphone_png_to_rgb, convert_iphone_png_to_rgb)
58 | SET_FLAG_FUNC(Set_flip_vertically_on_load, set_flip_vertically_on_load)
59 |
60 | #undef SET_FLAG_FUNC
61 |
62 | /*@@TODO: Image object
63 | * image = load_image(...)
64 | * Instead of passing the image data as a binary string, returns an image object
65 | * that holds the pointer to the data returned by stbi_load().
66 | * The data is retained until the object is destroyed.
67 | *
68 | * Methods:
69 | * image:data() -> returns the data as a binary string
70 | * image:ptr()
71 | * image:size()
72 | * image:width()
73 | * image:height()
74 | * image:channels()
75 | * image:free()
76 | *
77 | * Also, make write_xxx() functions accept a image object in lieu of data,w,h.
78 | *
79 | * Advantages: when the loaded image is to be passed to a C library that accepts
80 | * (ptr, size), with this interface we can just pass the pointer from C to Lua and
81 | * from Lua to C (zero-copy).
82 | */
83 |
84 | static int Load(lua_State *L)
85 | {
86 | int x, y, len, chansz;
87 | int channels;
88 | void *data;
89 | const char *filename = luaL_checkstring(L, 1);
90 | int desired_channels = optchannels(L, 2);
91 | int chantype = optchantype(L, 3, CHANTYPE_u8);
92 |
93 | switch(chantype)
94 | {
95 | case CHANTYPE_u8:
96 | chansz = sizeof(stbi_uc);
97 | data = stbi_load(filename, &x, &y, &channels, desired_channels);
98 | break;
99 | case CHANTYPE_u16:
100 | chansz = sizeof(stbi_us);
101 | data = stbi_load_16(filename, &x, &y, &channels, desired_channels);
102 | break;
103 | case CHANTYPE_f:
104 | chansz = sizeof(float);
105 | data = stbi_loadf(filename, &x, &y, &channels, desired_channels);
106 | break;
107 | default:
108 | return unexpected(L);
109 | }
110 |
111 | if(!data) return Error(L);
112 | channels = (desired_channels > 0) ? desired_channels : channels;
113 | len = x * y * channels * chansz;
114 | lua_pushlstring(L, (const char*)data, len);
115 | stbi_image_free((void*)data);
116 | lua_pushinteger(L, x);
117 | lua_pushinteger(L, y);
118 | pushchannels(L, channels);
119 | /* note that this function returns the used no. of channels, while stbi_load()
120 | * returns the channels in file even if it is not the used number */
121 | return 4;
122 | }
123 |
124 |
125 | static int Set_gamma_and_scale(lua_State *L)
126 | {
127 | float gamma = luaL_checknumber(L, 1);
128 | float scale = luaL_checknumber(L, 2);
129 | stbi_hdr_to_ldr_gamma(gamma);
130 | stbi_hdr_to_ldr_scale(scale);
131 | stbi_ldr_to_hdr_gamma(gamma);
132 | stbi_ldr_to_hdr_scale(scale);
133 | return 0;
134 | }
135 |
136 | static int Gamma_and_scale(lua_State *L)
137 | {
138 | lua_pushnumber(L, stbi__l2h_gamma);
139 | lua_pushnumber(L, stbi__l2h_scale);
140 | // lua_pushnumber(L, stbi__h2l_gamma_i);
141 | // lua_pushnumber(L, stbi__h2l_scale_i);
142 | return 2;
143 | }
144 |
145 | static int Is_hdr(lua_State *L)
146 | {
147 | const char *filename = luaL_checkstring(L, 1);
148 | lua_pushboolean(L, stbi_is_hdr(filename));
149 | return 1;
150 | }
151 |
152 | static int Info(lua_State *L)
153 | {
154 | int x, y, channels;
155 | const char *filename = luaL_checkstring(L, 1);
156 |
157 | if(!stbi_info(filename, &x, &y, &channels))
158 | return Error(L);
159 |
160 | lua_pushinteger(L, x);
161 | lua_pushinteger(L, y);
162 | pushchannels(L, channels);
163 | return 3;
164 | }
165 |
166 | static int Reduce_to_u8(lua_State *L)
167 | {
168 | size_t len;
169 | void *inout;
170 | const char *data = luaL_checklstring(L, 1, &len);
171 | int w = luaL_checkinteger(L, 2);
172 | int h = luaL_checkinteger(L, 3);
173 | int channels = checkchannels(L, 4);
174 | int chantype = checkchantype(L, 5);
175 |
176 | switch(chantype)
177 | {
178 | case CHANTYPE_u8:
179 | lua_pushlstring(L, data, len);
180 | return 1;
181 | case CHANTYPE_u16:
182 | if(len != (size_t)(w*h*channels*sizeof(stbi_us)))
183 | return luaL_error(L, "invalid data length");
184 | inout = STBI_MALLOC(len);
185 | memcpy(inout, data, len);
186 | inout = stbi__convert_16_to_8((stbi_us*)inout, w, h, channels);
187 | break;
188 | case CHANTYPE_f:
189 | if(len != (size_t)(w*h*channels*sizeof(float)))
190 | return luaL_error(L, "invalid data length");
191 | inout = STBI_MALLOC(len);
192 | memcpy(inout, data, len);
193 | inout = stbi__hdr_to_ldr((float*)inout, w, h, channels);
194 | break;
195 | default:
196 | return unexpected(L);
197 | }
198 |
199 | if(!inout) return Error(L);
200 | len = (size_t)(w*h*channels);
201 | lua_pushlstring(L, (const char*)inout, len);
202 | STBI_FREE(inout);
203 | return 1;
204 |
205 | }
206 |
207 |
208 | static const struct luaL_Reg Functions[] =
209 | {
210 | { "info", Info },
211 | { "reset_load_flags", Reset_load_flags },
212 | { "unpremultiply_on_load", Set_unpremultiply_on_load },
213 | { "convert_iphone_png_to_rgb", Convert_iphone_png_to_rgb },
214 | { "flip_vertically_on_load", Set_flip_vertically_on_load },
215 | { "load", Load },
216 | { "set_gamma_and_scale", Set_gamma_and_scale },
217 | { "gamma_and_scale", Gamma_and_scale },
218 | { "is_hdr", Is_hdr },
219 | { "reduce_to_u8", Reduce_to_u8 },
220 | { NULL, NULL } /* sentinel */
221 | };
222 |
223 |
224 | void moonimage_open_load(lua_State *L)
225 | {
226 | luaL_setfuncs(L, Functions, 0);
227 | }
228 |
229 |
230 |
--------------------------------------------------------------------------------
/src/main.c:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | #include "internal.h"
27 |
28 | static lua_State *moonimage_L = NULL;
29 |
30 | static void AtExit(void)
31 | {
32 | if(moonimage_L)
33 | {
34 | moonimage_L = NULL;
35 | }
36 | }
37 |
38 | static int AddVersions(lua_State *L)
39 | /* Add version strings to the gl table */
40 | {
41 | lua_pushstring(L, "_VERSION");
42 | lua_pushstring(L, "MoonImage "MOONIMAGE_VERSION);
43 | lua_settable(L, -3);
44 | return 0;
45 | }
46 |
47 |
48 | int luaopen_moonimage(lua_State *L)
49 | /* Lua calls this function to load the module */
50 | {
51 | moonimage_L = L;
52 |
53 | malloc_init(L);
54 | atexit(AtExit);
55 |
56 | lua_newtable(L); /* the module table */
57 | AddVersions(L);
58 |
59 | /* add functions: */
60 | moonimage_open_load(L);
61 | moonimage_open_write(L);
62 | moonimage_open_perlin(L);
63 |
64 | #if 0 //@@
65 | /* Add functions implemented in Lua */
66 | lua_pushvalue(L, -1); lua_setglobal(L, "moonimage");
67 | if(luaL_dostring(L, "require('moonimage.utils')") != 0) lua_error(L);
68 | lua_pushnil(L); lua_setglobal(L, "moonimage");
69 | #endif
70 |
71 | return 1;
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/src/moonimage.h:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | /****************************************************************************
27 | * MoonImage library - C API *
28 | ****************************************************************************/
29 |
30 | #ifndef moonimageDEFINED
31 | #define moonimageDEFINED
32 |
33 | #include
34 | #include "lualib.h"
35 | #include "lauxlib.h"
36 | #include "compat-5.3.h"
37 |
38 | #define MOONIMAGE_VERSION "0.3"
39 |
40 | #endif /* moonimageDEFINED */
41 |
42 |
--------------------------------------------------------------------------------
/src/perlin.c:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2019 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | #include "internal.h"
27 |
28 | /* Currently stb_perlin.h lacks a mechanism to make its functions static, such as
29 | * STB_IMAGE_STATIC in stb_image.h, so we prepend our moonimage_ prefix.
30 | */
31 | #define stb_perlin_noise3_internal moonimage_stb_perlin_noise3_internal
32 | float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
33 | #define stb_perlin_noise3 moonimage_stb_perlin_noise3
34 | float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
35 | #define stb_perlin_noise3_seed moonimage_stb_perlin_noise3_seed
36 | float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed);
37 | #define stb_perlin_ridge_noise3 moonimage_stb_perlin_ridge_noise3
38 | float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
39 | #define stb_perlin_fbm_noise3 moonimage_stb_perlin_fbm_noise3
40 | float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
41 | #define stb_perlin_turbulence_noise3 moonimage_stb_perlin_turbulence_noise3
42 | float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
43 | #define stb_perlin_noise3_wrap_nonpow2 moonimage_stb_perlin_noise3_wrap_nonpow2
44 | float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
45 |
46 | #define STB_PERLIN_IMPLEMENTATION
47 | #include "stb_perlin.h"
48 |
49 | /*------------------------------------------------------------------------------*
50 | | Perlin noise |
51 | *------------------------------------------------------------------------------*/
52 |
53 | static int Perlin(lua_State *L)
54 | {
55 | float value;
56 | float x = luaL_checknumber(L, 1);
57 | float y = luaL_optnumber(L, 2, 0);
58 | float z = luaL_optnumber(L, 3, 0);
59 | int x_wrap = luaL_optinteger(L, 4, 0);
60 | int y_wrap = luaL_optinteger(L, 5, 0);
61 | int z_wrap = luaL_optinteger(L, 6, 0);
62 | int seed = luaL_optinteger(L, 7, 0); /* 0-256 */
63 | value = stb_perlin_noise3_seed(x, y, z, x_wrap, y_wrap, z_wrap, seed);
64 | //@@value = stb_perlin_noise3_wrap_nonpow2(x, y, z, x_wrap, y_wrap, z_wrap, seed);
65 | /* Clamp between -1 and 1, just to be sure */
66 | if(value < -1.0f) value=-1.0f; else if(value > 1.0f) value=1.0f;
67 | lua_pushnumber(L, value);
68 | return 1;
69 | }
70 |
71 | static const struct luaL_Reg Functions[] =
72 | {
73 | { "perlin", Perlin},
74 | { NULL, NULL } /* sentinel */
75 | };
76 |
77 | void moonimage_open_perlin(lua_State *L)
78 | {
79 | luaL_setfuncs(L, Functions, 0);
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/src/utils.c:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | #include "internal.h"
27 |
28 | /*------------------------------------------------------------------------------*
29 | | Misc utilities |
30 | *------------------------------------------------------------------------------*/
31 |
32 | int noprintf(const char *fmt, ...)
33 | { (void)fmt; return 0; }
34 |
35 | int notavailable(lua_State *L, ...)
36 | {
37 | return luaL_error(L, "function not available in this version");
38 | }
39 |
40 | /*------------------------------------------------------------------------------*
41 | | Malloc |
42 | *------------------------------------------------------------------------------*/
43 |
44 | /* We do not use malloc(), free() etc directly. Instead, we inherit the memory
45 | * allocator from the main Lua state instead (see lua_getallocf in the Lua manual)
46 | * and use that.
47 | *
48 | * By doing so, we can use an alternative malloc() implementation without recompiling
49 | * this library (we have needs to recompile lua only, or execute it with LD_PRELOAD
50 | * set to the path to the malloc library we want to use).
51 | */
52 | static lua_Alloc Alloc = NULL;
53 | static void* AllocUd = NULL;
54 |
55 | void malloc_init(lua_State *L)
56 | {
57 | if(Alloc) unexpected(L);
58 | Alloc = lua_getallocf(L, &AllocUd);
59 | }
60 |
61 | static void* Malloc_(size_t size)
62 | { return Alloc ? Alloc(AllocUd, NULL, 0, size) : NULL; }
63 |
64 | static void Free_(void *ptr)
65 | { if(Alloc) Alloc(AllocUd, ptr, 0, 0); }
66 |
67 | void *Malloc(lua_State *L, size_t size)
68 | {
69 | void *ptr = Malloc_(size);
70 | if(ptr==NULL)
71 | { luaL_error(L, errstring(ERR_MEMORY)); return NULL; }
72 | memset(ptr, 0, size);
73 | //DBG("Malloc %p\n", ptr);
74 | return ptr;
75 | }
76 |
77 | void *MallocNoErr(lua_State *L, size_t size) /* do not raise errors (check the retval) */
78 | {
79 | void *ptr = Malloc_(size);
80 | (void)L;
81 | if(ptr==NULL)
82 | return NULL;
83 | memset(ptr, 0, size);
84 | //DBG("MallocNoErr %p\n", ptr);
85 | return ptr;
86 | }
87 |
88 | char *Strdup(lua_State *L, const char *s)
89 | {
90 | size_t len = strnlen(s, 256);
91 | char *ptr = (char*)Malloc(L, len + 1);
92 | if(len>0)
93 | memcpy(ptr, s, len);
94 | ptr[len]='\0';
95 | return ptr;
96 | }
97 |
98 |
99 | void Free(lua_State *L, void *ptr)
100 | {
101 | (void)L;
102 | //DBG("Free %p\n", ptr);
103 | if(ptr) Free_(ptr);
104 | }
105 |
106 | /*------------------------------------------------------------------------------*
107 | | Custom luaL_checkxxx() style functions |
108 | *------------------------------------------------------------------------------*/
109 |
110 | int checkboolean(lua_State *L, int arg)
111 | {
112 | if(!lua_isboolean(L, arg))
113 | return (int)luaL_argerror(L, arg, "boolean expected");
114 | return lua_toboolean(L, arg);
115 | }
116 |
117 |
118 | int testboolean(lua_State *L, int arg, int *err)
119 | {
120 | if(!lua_isboolean(L, arg))
121 | { *err = ERR_TYPE; return 0; }
122 | *err = 0;
123 | return lua_toboolean(L, arg);
124 | }
125 |
126 |
127 | int optboolean(lua_State *L, int arg, int d)
128 | {
129 | if(!lua_isboolean(L, arg))
130 | return d;
131 | return lua_toboolean(L, arg);
132 | }
133 |
134 | /* Color channels (enum) ----------------------------------------------------*/
135 |
136 | int checkchannels(lua_State *L, int arg)
137 | {
138 | const char *s = luaL_checkstring(L, arg);
139 | #define CASE(CODE,str) if((strcmp(s, str)==0)) return CODE
140 | // CASE(CHAN_default, "default");
141 | CASE(CHAN_y, "y");
142 | CASE(CHAN_ya, "ya");
143 | CASE(CHAN_rgb, "rgb");
144 | CASE(CHAN_rgba, "rgba");
145 | #undef CASE
146 | return luaL_argerror(L, arg, badvalue(L,s));
147 | }
148 |
149 | int optchannels(lua_State *L, int arg)
150 | {
151 | if(lua_isnoneornil(L, arg))
152 | return CHAN_default;
153 | return checkchannels(L, arg);
154 | }
155 |
156 | int pushchannels(lua_State *L, int val)
157 | {
158 | switch(val)
159 | {
160 | #define CASE(CODE,str) case CODE: lua_pushstring(L, str); break
161 | // CASE(CHAN_default, "default");
162 | CASE(CHAN_y, "y");
163 | CASE(CHAN_ya, "ya");
164 | CASE(CHAN_rgb, "rgb");
165 | CASE(CHAN_rgba, "rgba");
166 | #undef CASE
167 | default:
168 | return unexpected(L);
169 | }
170 | return 1;
171 | }
172 |
173 | /* Color channel type (enum) ------------------------------------------------*/
174 |
175 | int checkchantype(lua_State *L, int arg)
176 | {
177 | const char *s = luaL_checkstring(L, arg);
178 | #define CASE(CODE,str) if((strcmp(s, str)==0)) return CODE
179 | CASE(CHANTYPE_u8, "u8");
180 | CASE(CHANTYPE_u16, "u16");
181 | CASE(CHANTYPE_f, "f");
182 | #undef CASE
183 | return luaL_argerror(L, arg, badvalue(L,s));
184 | }
185 |
186 | int optchantype(lua_State *L, int arg, int defval)
187 | {
188 | if(lua_isnoneornil(L, arg))
189 | return defval;
190 | return checkchantype(L, arg);
191 | }
192 |
193 | int pushchantype(lua_State *L, int val)
194 | {
195 | switch(val)
196 | {
197 | #define CASE(CODE,str) case CODE: lua_pushstring(L, str); break
198 | CASE(CHANTYPE_u8, "u8");
199 | CASE(CHANTYPE_u16, "u16");
200 | CASE(CHANTYPE_f, "f");
201 | #undef CASE
202 | default:
203 | return unexpected(L);
204 | }
205 | return 1;
206 | }
207 |
208 | /*------------------------------------------------------------------------------*
209 | | Internal error codes |
210 | *------------------------------------------------------------------------------*/
211 |
212 | const char* errstring(int err)
213 | {
214 | switch(err)
215 | {
216 | case 0: return "success";
217 | case ERR_GENERIC: return "generic error";
218 | case ERR_TABLE: return "not a table";
219 | case ERR_EMPTY: return "empty list";
220 | case ERR_TYPE: return "invalid type";
221 | case ERR_VALUE: return "invalid value";
222 | case ERR_NOTPRESENT: return "missing";
223 | case ERR_MEMORY: return "out of memory";
224 | case ERR_LENGTH: return "invalid length";
225 | case ERR_POOL: return "elements are not from the same pool";
226 | case ERR_BOUNDARIES: return "invalid boundaries";
227 | case ERR_UNKNOWN: return "unknown field name";
228 | default:
229 | return "???";
230 | }
231 | return NULL; /* unreachable */
232 | }
233 |
234 |
--------------------------------------------------------------------------------
/src/write.c:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 | *
3 | * Copyright (c) 2017 Stefano Trettel
4 | *
5 | * Software repository: MoonImage, https://github.com/stetre/moonimage
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in all
15 | * copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * SOFTWARE.
24 | */
25 |
26 | #include "internal.h"
27 |
28 | #define STB_IMAGE_WRITE_IMPLEMENTATION
29 | #define STB_IMAGE_WRITE_STATIC
30 | #include "stb_image_write.h"
31 |
32 | static int Error(lua_State *L)
33 | {
34 | return luaL_error(L, "operation failed");
35 | }
36 |
37 | static int Write_png(lua_State *L)
38 | {
39 | size_t len;
40 | const char *filename = luaL_checkstring(L, 1);
41 | int w = luaL_checkinteger(L, 2);
42 | int h = luaL_checkinteger(L, 3);
43 | int channels = checkchannels(L, 4);
44 | const void *data = luaL_checklstring(L, 5, &len);
45 | int stride = luaL_optinteger(L, 6, 0);
46 | if(stride < 0)
47 | return luaL_argerror(L, 6, "stride must be non negative");
48 | if(len != (size_t)(w*h*channels))
49 | return luaL_error(L, "invalid data length");
50 | if(!stbi_write_png(filename, w, h, channels, data, stride)) return Error(L);
51 | return 0;
52 | }
53 |
54 | static int Write_bmp(lua_State *L)
55 | {
56 | size_t len;
57 | const char *filename = luaL_checkstring(L, 1);
58 | int w = luaL_checkinteger(L, 2);
59 | int h = luaL_checkinteger(L, 3);
60 | int channels = checkchannels(L, 4);
61 | const void *data = luaL_checklstring(L, 5, &len);
62 | if(len != (size_t)(w*h*channels))
63 | return luaL_error(L, "invalid data length");
64 | if(!stbi_write_bmp(filename, w, h, channels, data)) return Error(L);
65 | return 0;
66 | }
67 |
68 | static int Write_tga(lua_State *L)
69 | {
70 | int rc;
71 | size_t len;
72 | const char *filename = luaL_checkstring(L, 1);
73 | int w = luaL_checkinteger(L, 2);
74 | int h = luaL_checkinteger(L, 3);
75 | int channels = checkchannels(L, 4);
76 | const void *data = luaL_checklstring(L, 5, &len);
77 | int rle = optboolean(L, 6, 0);
78 | if(len != (size_t)(w*h*channels))
79 | return luaL_error(L, "invalid data length");
80 | if(!rle) stbi_write_tga_with_rle = 0;
81 | rc = stbi_write_tga(filename, w, h, channels, data);
82 | stbi_write_tga_with_rle = 1;
83 | if(!rc) return Error(L);
84 | return 0;
85 | }
86 |
87 |
88 | static int Write_hdr(lua_State *L)
89 | {
90 | size_t len;
91 | const char *filename = luaL_checkstring(L, 1);
92 | int w = luaL_checkinteger(L, 2);
93 | int h = luaL_checkinteger(L, 3);
94 | int channels = checkchannels(L, 4);
95 | const void *data = luaL_checklstring(L, 5, &len);
96 | if(len != (size_t)(w*h*channels*sizeof(float)))
97 | return luaL_error(L, "invalid data length");
98 | if(!stbi_write_hdr(filename, w, h, channels, (const float*)data)) return Error(L);
99 | return 0;
100 | }
101 |
102 |
103 | static int Write_jpg(lua_State *L)
104 | {
105 | int rc;
106 | size_t len;
107 | const char *filename = luaL_checkstring(L, 1);
108 | int w = luaL_checkinteger(L, 2);
109 | int h = luaL_checkinteger(L, 3);
110 | int channels = checkchannels(L, 4);
111 | const void *data = luaL_checklstring(L, 5, &len);
112 | int quality = luaL_checkinteger(L, 6);
113 | if((quality < 1) || (quality > 100))
114 | return luaL_argerror(L, 6, "quality must be between 1 (min) and 100 (max)");
115 | if(len != (size_t)(w*h*channels))
116 | return luaL_error(L, "invalid data length");
117 | rc = stbi_write_jpg(filename, w, h, channels, data, quality);
118 | if(!rc) return Error(L);
119 | return 0;
120 | }
121 |
122 | static const struct luaL_Reg Functions[] =
123 | {
124 | { "write_png", Write_png },
125 | { "write_bmp", Write_bmp },
126 | { "write_tga", Write_tga },
127 | { "write_hdr", Write_hdr },
128 | { "write_jpg", Write_jpg },
129 | { NULL, NULL } /* sentinel */
130 | };
131 |
132 |
133 | void moonimage_open_write(lua_State *L)
134 | {
135 | luaL_setfuncs(L, Functions, 0);
136 | }
137 |
138 |
139 |
--------------------------------------------------------------------------------
/thirdparty/asciidoctor-styles-license:
--------------------------------------------------------------------------------
1 | The CSS used for the Reference Manual is taken from the
2 | Asciidoctor styles project
3 | (https://github.com/asciidoctor/asciidoctor-stylesheet-factory ).
4 |
5 | Below is a copy of the Asciidoctor styles copyright notice.
6 |
7 | Stefano Trettel
8 |
9 | ========================================================================
10 |
11 | Asciidoctor styles
12 | ------------------
13 |
14 | Copyright (c) 2013 Dan Allen
15 |
16 | MIT License
17 |
18 | Permission is hereby granted, free of charge, to any person obtaining
19 | a copy of this software and associated documentation files (the
20 | "Software"), to deal in the Software without restriction, including
21 | without limitation the rights to use, copy, modify, merge, publish,
22 | distribute, sublicense, and/or sell copies of the Software, and to
23 | permit persons to whom the Software is furnished to do so, subject to
24 | the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be
27 | included in all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 |
37 |
38 | Other licensed work
39 | -------------------
40 |
41 | - Foundation 4 by Zurb, on which the themes are built, is licensed under the
42 | Apache License, v2.0:
43 |
44 | http://apache.org/licenses/LICENSE-2.0
45 | http://foundation.zurb.com
46 |
47 | - The riak theme is derived from the Riak documentation theme by Basho,
48 | licensed under the Creative Commons Attribution 3.0 Unported License:
49 |
50 | http://creativecommons.org/licenses/by/3.0/us
51 | http://docs.basho.org
52 |
53 | - The iconic theme is inspired by O'Reilly typography and Atlas manual.
54 |
55 | http://oreilly.com
56 |
--------------------------------------------------------------------------------
/thirdparty/lua-compat-5.3-license:
--------------------------------------------------------------------------------
1 | The src/compat-5.3.h and src/compat-5.3.c files are taken from:
2 | https://github.com/keplerproject/lua-compat-5.3
3 |
4 | Below is a copy of the original copyright notice, from the same source.
5 |
6 | Stefano Trettel
7 |
8 | ===========================================================================
9 |
10 | The MIT License (MIT)
11 |
12 | Copyright (c) 2015 Kepler Project.
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy of
15 | this software and associated documentation files (the "Software"), to deal in
16 | the Software without restriction, including without limitation the rights to
17 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
18 | the Software, and to permit persons to whom the Software is furnished to do so,
19 | subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included in all
22 | copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
26 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
28 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 |
--------------------------------------------------------------------------------
/thirdparty/powered-by-lua-license:
--------------------------------------------------------------------------------
1 | The 'powered by Lua' logo (doc/powered-by-lua.gif ) is taken from:
2 | http://www.lua.org/images .
3 |
4 | Below is a copy of the copyright notice from the same web-page.
5 |
6 | Stefano Trettel
7 |
8 | ===========================================================================
9 | Copyright © 1998 Lua.org. Graphic design by Alexandre Nakonechnyj.
10 |
11 | Permission is hereby granted, without written agreement and without license
12 | or royalty fees, to use, copy, and distribute this logo for any purpose,
13 | including commercial applications, subject to the following conditions:
14 |
15 | - The origin of this logo must not be misrepresented; you must not claim that
16 | you drew the original logo.
17 | - The only modification you can make is to adapt the orbiting text to your
18 | product name.
19 | - The logo can be used in any scale as long as the relative proportions of its
20 | elements are maintained.
21 |
--------------------------------------------------------------------------------
/thirdparty/stb-license:
--------------------------------------------------------------------------------
1 | The following files are taken from the STB libraries:
2 | - src/include/stb_image.h
3 | - src/include/stb_image_write.h
4 | (Taken from https://github.com/nothings/stb)
5 |
6 | Below is a copy of their copyright statement.
7 |
8 | Stefano Trettel
9 |
10 | ===========================================================================
11 |
12 | /*
13 | ------------------------------------------------------------------------------
14 | This software is available under 2 licenses -- choose whichever you prefer.
15 | ------------------------------------------------------------------------------
16 | ALTERNATIVE A - MIT License
17 | Copyright (c) 2017 Sean Barrett
18 | Permission is hereby granted, free of charge, to any person obtaining a copy of
19 | this software and associated documentation files (the "Software"), to deal in
20 | the Software without restriction, including without limitation the rights to
21 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
22 | of the Software, and to permit persons to whom the Software is furnished to do
23 | so, subject to the following conditions:
24 | The above copyright notice and this permission notice shall be included in all
25 | copies or substantial portions of the Software.
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 | ------------------------------------------------------------------------------
34 | ALTERNATIVE B - Public Domain (www.unlicense.org)
35 | This is free and unencumbered software released into the public domain.
36 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
37 | software, either in source code form or as a compiled binary, for any purpose,
38 | commercial or non-commercial, and by any means.
39 | In jurisdictions that recognize copyright laws, the author or authors of this
40 | software dedicate any and all copyright interest in the software to the public
41 | domain. We make this dedication for the benefit of the public at large and to
42 | the detriment of our heirs and successors. We intend this dedication to be an
43 | overt act of relinquishment in perpetuity of all present and future rights to
44 | this software under copyright law.
45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
49 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
50 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51 | ------------------------------------------------------------------------------
52 | */
53 |
--------------------------------------------------------------------------------