DevIL_manual.texi 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. \input texinfo @c -*-texinfo-*-
  2. @c %**start of header
  3. @setfilename DevIL_manual.info
  4. @settitle Developer's Image Library manual
  5. @documentencoding UTF-8
  6. @c %**end of header
  7. @c QUITE IMPORTANT: This document is revision-controlled.
  8. @c Revision-control systems operate on per-line basis, so they
  9. @c will like if editors write using 'one sentence = one line' rule.
  10. @c just some fancy stuff like VERSION and UPDATED generation
  11. @c version.texi is generated automatically
  12. @include version.texi
  13. @copying
  14. This is @code{DevIL @value{VERSION}} manual.
  15. Last update is from @value{UPDATED}.
  16. Copyright @copyright{} 2008,2009 Denton Woods, Matěj Týč
  17. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation;
  18. with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
  19. A copy of the license is included in the section entitled ``GNU Free Documentation License''.
  20. @end copying
  21. @titlepage
  22. @title Developer's Image Library manual
  23. @sp 1
  24. @center @image{images/DevIL,14.9cm}
  25. @c The following two commands start the copyright page.
  26. @page
  27. @vskip 0pt plus 1filll
  28. @insertcopying
  29. @end titlepage
  30. @c Output the table of contents at the beginning.
  31. @contents
  32. @node Top
  33. @top IL manual
  34. This is a manual describing IL part of @code{DevIL} -- handling images.
  35. @menu
  36. * Introduction:: General intro
  37. * Basic usage:: How to write your first code
  38. * Image management:: How to manage images :-)
  39. * Error handling:: If you encounter an error...
  40. * Image manipulation:: How to manipulate with images using ILU
  41. * Common #defines:: #defines you are likely to come across when using DevIL
  42. * Sample program:: If you want to get going quickly
  43. * Functions index:: Index of IL and ILU functions
  44. @end menu
  45. @node Introduction
  46. @chapter Introduction
  47. @section General introduction
  48. Developer's Image Library was previously called OpenIL, but due to trademark issues, @code{OpenIL} is now known as @code{DevIL}.
  49. @code{DevIL} is an Open Source programming library for programmers to incorporate into their own programs.
  50. @code{DevIL} loads and saves a large variety of images for use in a software developer's program.
  51. This library is capable of manipulating images in various ways and passing image information to display APIs, such as OpenGL and Direct3D.
  52. The purpose of this manual is to guide users in coding with the Developer's Image Library.
  53. This manual is for users proficient in C and with competent knowledge of the integrated development environment (IDE) or compiler they are using.
  54. @section Library Reference
  55. Several times throughout this document, the three different sub-libraries of @code{DevIL} are referenced as IL, ILU and ILUT.
  56. IL refers to the base library for loading, saving and converting images.
  57. ILU refers to the middle level library for image manipulation.
  58. ILUT refers to the high level library for displaying images.
  59. Functions in IL, ILU and ILUT are prefixed by ‘il', ‘ilu' and ‘ilut', respectively.
  60. @c @node Library setup
  61. @chapter Library setup
  62. @section Microsoft Visual C++ setup
  63. @code{DevIL} setup for Windows is straightforward.
  64. Unzip @code{DevIL} in an empty directory.
  65. If using WinZip, check the ``Use folder names'' box before unzipping.
  66. Use the -d command line option if using pkunzip.
  67. Then double-click on the ImageLib.sln file in the install directory to load the @code{DevIL} workspace in Microsoft Visual C++ (MSVC++).
  68. @subsection Directories
  69. You will need to change some directory settings in MSVC++ to get @code{DevIL} working.
  70. @enumerate
  71. @item Navigate to the Tools menu and select Options.
  72. @item Click on the Directories tab.
  73. @item Under Show directories for, select ``Include files''.
  74. @item Click the New button (to the left of the red 'X')
  75. @item Type the directory @code{DevIL} is installed in, plus @file{\Include}.
  76. For example, if you installed @code{DevIL} to E:\ImageLib, enter @file{E:\ImageLib\Include}.
  77. @image{images/devil_msvc_include}
  78. @item Under Show directories for, click on ``Library files''.
  79. @item Click the New button (to the left of the red 'X').
  80. @item Type the directory @code{DevIL} is installed in, plus @file{\Lib}.
  81. For example, if you installed @code{DevIL} to E:\ImageLib, enter @file{E:\ImageLib\Lib}.
  82. @image{images/devil_msvc_lib}
  83. @item Click the New button (to the left of the red ‘X').
  84. @item Type the directory @code{DevIL} is installed in, plus @file{\Lib\Debug}.
  85. In the previous example, you would enter @file{E:\ImageLib\Lib\Debug}.
  86. @item Choose OK.
  87. @end enumerate
  88. @subsection MSVC++ Bug Workaround
  89. Microsoft Visual C++ 6.0 has a bug that prevents debugging of a project.
  90. The bug appears to occur when you use a #pragma to link a .lib file and link it via another method.
  91. The header files @file{il.h}, @file{ilu.h} and @file{ilut.h} automatically link the .lib files in via a @code{#pragma} for convenience.
  92. To prevent this bug, check for and remove these:
  93. @itemize
  94. @item @file{devil.lib}, @file{devil-d.lib}, @file{ilu.lib}, @file{ilu-d.lib}, @file{ilut.lib} and @file{ilut-d.lib} in your project settings (Project – Settings menu).
  95. @item @file{devil.lib}, @file{devil-d.lib}, @file{ilu.lib}, @file{ilu-d.lib}, @file{ilut.lib} and @file{ilut-d.lib} in your project's workspace.
  96. Some people link libraries into their project this way, which really should be discouraged, due to the hardcoded paths.
  97. @end itemize
  98. @subsection Multithreading
  99. @code{DevIL} takes advantage of the multithreaded standard @code{LIBC} DLLs.
  100. To use file streams with @code{DevIL}, you must change the project settings of your project.
  101. If you do not perform these steps, your program will crash whenever you attempt to use a @code{DevIL} file stream.
  102. Generally, @code{DevIL} is not thread safe.
  103. You should make sure that threads in your application do not use @code{DevIL} at the same time.
  104. @enumerate
  105. @item Navigate to the Project menu and choose Settings.
  106. @item Click the C/C++ tab.
  107. @item Change the Category drop-down menu to read Code Generation.
  108. @item Change the Use run-time library drop-down menu to Multithreaded DLL if the Settings For menu says Win32 Release.
  109. Change the Use run-time library drop-down menu to Debug Multithreaded DLL if the Settings For menu says Win32 Debug.
  110. @item Choose OK.
  111. @end enumerate
  112. @section @code{DJGPP} Setup
  113. Setting up @code{DevIL} in DJGPP requires the following steps:
  114. @enumerate
  115. @item Unzip @code{DevIL} in an empty directory.
  116. If using WinZip, check the ``Use folder names'' box before unzipping.
  117. Use the -d command line option if using pkunzip.
  118. @item Create a new subdirectory called ‘il' in your @code{DJGPP} include directory.
  119. @item Copy the files to their respective places:
  120. @itemize
  121. @item To use the precompiled libraries, copy @file{libil.a}, @file{libilu.a} and @file{libilut.a} from ImageLib\lib\djgpp to your @code{DJGPP} lib directory.
  122. Then copy @file{il.h}, @file{ilu.h} and @file{ilut.h} from your ImageLib\lib\il directory to your @code{DJGPP} include\il directory.
  123. @item To compile the library yourself, change directories to ImageLib\Makefiles\Djgpp.
  124. This folder contains only a makefile for @code{DJGPP}.
  125. Simply type @command{make}, and the makefile will compile @code{DevIL} and copy the files to their respective locations.
  126. @end itemize
  127. @end enumerate
  128. To compile with @code{DevIL} in DJGPP, add @option{-lil} to your command line.
  129. To also use ILU and ILUT, use @option{-lilu} and @option{-lilut}, respectively.
  130. @section General GCC-based (Linux, Cygwin, Max OS X, etc.) Setup
  131. Setting up @code{DevIL} in this environment requires the following steps:
  132. @enumerate
  133. @item Unpack @code{DevIL} to your favourite build area: Typically this is done by running @command{tar -xvvf devil-xxx.tar.gz}
  134. @item Go to the root devil directory and run @command{./configure <your-favourite options>}
  135. TIP: Typically, you will want to specify @code{--prefix=/usr} (where to install @code{DevIL}), @code{--enable-ILU} and/or @code{--enable-ILUT} and probably also @code{--with-examples}.
  136. Running @command{configure --help} gives you an exhaustive list of possibilities how to tweak @code{DevIL} build.
  137. @item If no errors occured and you are satisfied with the configure report, you can compile it by running @command{make}
  138. TIP: You can run @command{make -j3} if you have a dual-core processor. Generally, if you replace the number '3' with 'number of CPU cores' + 1, you are likely to get the job done in the shortest time.
  139. @item Run @command{make check} to check whether everything works as it should.
  140. @xref{tests}, for hints what to do if a test fails.
  141. @item Install @code{DevIL} by running @command{make install} as superuser.
  142. TIP: You can override variables at make time if you forgot to do that at configure time.
  143. For instance, you can install by @command{make install prefix=/usr}
  144. @end enumerate
  145. In order to link to @code{DevIL}, you may use autotools with @code{libtool}, which means to link either with @file{libIL.la} or @file{libILU.la} or with @file{libILUT.la} depending what level of functionality you require.
  146. You may decide to use a monolithic build of the library and you then link with @file{libDevIL.la}.
  147. The best way is to have this code in your @file{configure.ac} file:
  148. @example
  149. ...
  150. @i{dnl Check for libtool (older macro for this is AC_PROG_LIBTOOL)}
  151. LT_INIT
  152. ...
  153. @i{# Check for libs we need for our program now}
  154. @i{dnl Check that we have the header}
  155. AC_CHECK_HEADER([IL/il.h])
  156. @i{dnl Check for the IL part on DevIL on unix-like systems}
  157. PKG_CHECK_MODULES([DEVIL],
  158. [IL ILU ILUT])
  159. @i{dnl Check that DevIL library exists (good for Windows)}
  160. AC_CHECK_LIB([DevIL], [main], [LIBS_WE_NEED="-lDevIL $LIBS_WE_NEED"])
  161. ...
  162. @i{dnl Now export the variable that contains libraries}
  163. @i{dnl so we can use it in makefiles}
  164. AC_SUBST([LIBS_WE_NEED])
  165. AC_SUBST([DEVIL_CFLAGS DEVIL_LIBS])
  166. ...
  167. @end example
  168. If you are skilled with automake, you may link with the libtool files directly, which is more portable (@code{pkg-config} currently breaks cross-compilation).
  169. If you use an IDE or if you don't like autotools (which is a big mistake, by the way :-), then you may use @file{pkg-config} as a program.
  170. This is not recommended if you intend to use @code{DevIL} in a cross-platform programs.
  171. You can get libraries you need to link to by running @command{pkg-config IL --libs}. Again, you decide whether you need @code{IL}, @code{ILU} or @code{ILUT}.
  172. Also pass @command{pkg-config IL --cflags} to the compiler!
  173. If you are a happy IDE user, you have to write this commands in the backquotes like @command{`pkg-config ILUT --libs`} into some text boxes that allow you to specify additional @code{LDFLAGS}.
  174. @section Test and examples
  175. @anchor{tests}
  176. @subsection Test suite
  177. @code{DevIL} now comes with a test suite.
  178. If you can use autotools to configure and compile it, you can also run the test suite by executing @command{make check} in the directory where you ran @command{configure}.
  179. There are following tests available:
  180. @itemize
  181. @item Format test: An image is generated and saved to disc.
  182. It is loaded afterwards and compared to the original.
  183. If they are pretty much the same, the test is passed.
  184. @item Format test 2 (coming soon): Some image formats can't be saved.
  185. So a test images are provided and loaded and compared.
  186. @end itemize
  187. @subsection Examples
  188. @code{IL} examples:
  189. @itemize
  190. @item Simple
  191. @item Read
  192. @item Override
  193. @end itemize
  194. Note: Those examples can be linked against @code{ILU}, but this is only because error report functions.
  195. @code{ILUT} examples:
  196. @itemize
  197. @item Allegro
  198. @item C++ wrapper
  199. @item SDL
  200. @item Volume
  201. @item OpenGL
  202. @end itemize
  203. @node Basic usage
  204. @chapter Basic usage
  205. You must initialize @code{DevIL}, or it will most certainly crash.
  206. You need to initialize each library (IL, ILU, and ILUT) separately.
  207. You do not need to initialize libraries you are not using, but keep in mind that the higher level libraries are dependent on the lower ones.
  208. For example, ILUT is dependent on ILU and IL, so you have to initialize IL and ILU as well.
  209. @section Initializing DevIL
  210. @findex ilInit
  211. @subsection IL Initialization
  212. Simply call the @code{ilInit} function with no parameters:
  213. @example
  214. // Initialize IL
  215. ilInit();
  216. @end example
  217. @findex iluInit
  218. @subsection ILU Initialization
  219. Call the @code{iluInit} function with no parameters:
  220. @example
  221. // Initialize ILU
  222. iluInit();
  223. @end example
  224. @subsection ILUT Initialization
  225. ILUT initialization is slightly more complex than IL and ILU initialization.
  226. The function you will use is @code{ilutRenderer}. You must call @code{ilutRenderer} before you use any ILUT functions.
  227. This function initializes ILUT support for the API you desire to use by a single parameter:
  228. @itemize
  229. @item @code{ILUT_OPENGL} -- Initializes ILUT's OpenGL support.
  230. @item @code{ILUT_ALLEGRO} -- Initializes ILUT's Allegro support.
  231. @item @code{ILUT_WIN32} -- Initializes ILUT's Windows GDI and DirectX 8 support.
  232. @end itemize
  233. An example of using @code{ilutRenderer} follows:
  234. @example
  235. // Initialize ILUT with OpenGL support.
  236. ilutRenderer(ILUT_OPENGL);
  237. @end example
  238. @section Image Name Handling
  239. Image names are @code{DevIL}'s way of keeping track of images it is currently containing.
  240. Some other image libraries return structs, but they generally seem more cluttered than @code{DevIL}'s image name handling.
  241. @example
  242. ILvoid ilGenImages(ILsizei Num, ILuint *Images);
  243. ILvoid ilBindImage(ILuint Image);
  244. ILvoid ilDeleteImages(ILsizei Num, ILuint *Images);
  245. @end example
  246. @findex ilGenImages
  247. @subsection Generating Image Names
  248. Use @code{ilGenImages} to generate a set of image names. @code{ilGenImages} accepts an array of ILuint to receive the generated image names.
  249. There are no guarantees about the order of the generated image names or any other predictable behaviour like this.
  250. If @code{ilDeleteImages} is called on an image name, @code{ilGenImages} will return that value afterward, until all deleted image names are used.
  251. This conserves memory and is generally quick.
  252. The only guarantee is that each member of the Images parameter (up to Num number of them) will have a new, unique value.
  253. @findex ilBindImage
  254. @subsection Binding Image Names
  255. @code{ilBindImage} binds the current image to the image described by the image name in Image.
  256. @code{DevIL} reserves the number zero for the default base image.
  257. If you pass a value for Image that was not generated by @code{ilGenImages}, @code{ilBindImage} automatically creates an image specified by the image name passed.
  258. An image must always be bound before you call any functions that operate on images and their data.
  259. When @code{DevIL} creates a new image, the image has the default properties of with a bit depth of 8.
  260. @code{DevIL} creates a new image when you call @code{ilBindImage} with an image name that has not been generated by @code{ilGenImages} or when you call @code{ilGenImages} specifically.
  261. @findex ilDeleteImages
  262. @subsection Deleting Image Names
  263. @code{ilDeleteImages} is the exact opposite of @code{ilGenImages} and even accepts the exact same parameters. @code{ilDeleteImages} deletes image names to free memory for subsequent operations.
  264. You should always call @code{ilDeleteImages} on images that are not in use anymore.
  265. When you delete an image, @code{DevIL} actually deletes all data and anything associate with it, so that @code{ilGenImages} can possibly use the image name later.
  266. @section File handling -- loading images
  267. @code{DevIL}'s main purpose is to load images.
  268. @code{DevIL}'s loading is designed to be extremely easy but very powerful.
  269. @xref{file_formats}, lists the image types @code{DevIL} is capable of loading.
  270. @code{DevIL} contains four loading functions to support different loading styles and loading from several different image sources.
  271. @example
  272. ILboolean ilLoadImage(const char *FileName);
  273. ILboolean ilLoad(ILenum Type, const char *FileName);
  274. ILboolean ilLoadF(ILenum Type, ILHANDLE File);
  275. ILboolean ilLoadL(ILenum Type, ILvoid *Lump, ILuint Size);
  276. @end example
  277. @findex ilLoadImage
  278. @subsection Loading from Files -- @code{ilLoadImage}
  279. @code{ilLoadImage} is the main @code{DevIL} loading function.
  280. All you do is pass @code{ilLoadImage} the filename of the image you wish to load. @code{ilLoadImage} takes care of the rest. @code{ilLoadImage} allows users to transparently load several different image formats uniformly.
  281. @code{DevIL}'s most powerful function is @code{ilLoadImage} because of this feature.
  282. Before loading the image, @code{ilLoadImage} must first determine the image format of the file. @code{ilLoadImage} performs the following steps:
  283. @enumerate
  284. @item Compares the filename's extension to any registered file handlers, allowing the registered file handlers to take precedence over the default @code{DevIL} file handlers.
  285. If the extension matches a registered file handler, @code{ilLoadImage} passes control to the file handler and returns.
  286. For more information on registering, refer to the section entitled (@pxref{registration}).
  287. @item Compares the filename's extension to the extensions natively supported by @code{DevIL}.
  288. If the extension matches a loading function's extension, @code{ilLoadImage} passes control to the file handler and returns.
  289. @item Examines the file for a header and tries to match it with a known type of image header.
  290. If a valid image header is found, @code{ilLoadImage} passes control to the appropriate file hander and returns.
  291. @item Returns @code{IL_FALSE}.
  292. @end enumerate
  293. @findex ilLoad
  294. @subsection Loading from Files -- @code{ilLoad}
  295. @code{DevIL}'s other file loading function is @code{ilLoad}. @code{ilLoad} is similar to @code{ilLoadImage} in many respects but different in other ways. @code{ilLoad} accepts two parameters: the type of image and the filename of the image.
  296. @code{ilLoad}'s type parameter is what differentiates it from @code{ilLoadImage}.
  297. Type can be any of the values listed in table B-2 in appendix B or the value @code{IL_TYPE_UNKNOWN}.
  298. If Type is a value from table B-1, @code{ilLoad} attempts to load the file as the specified type of image format.
  299. Only use this if you know what type of images you will be loading and want to bypass @code{DevIL}'s checks.
  300. If @code{IL_TYPE_UNKNOWN} is specified for Type, @code{ilLoad} behaves exactly like @code{ilLoadImage}.
  301. Refer to the previous section for detailed behaviour of these two functions.
  302. @findex ilLoadF
  303. @subsection Loading from File Streams -- @code{ilLoadF}
  304. @code{DevIL}'s file stream loading function is @code{ilLoadF}.
  305. @code{ilLoadF} is exactly equivalent to @code{ilLoad}, but instead of accepting a const char pointer, @code{ilLoadF} accepts an @code{ILHANDLE}.
  306. @code{DevIL} defines @code{ILHANDLE} as a void pointer via a typedef.
  307. Under normal circumstances, File will be a @code{FILE} struct pointer defined in @file{stdio.h}.
  308. @xref{registration}, for instructions on how to use your own file handling functions and file handles.
  309. @findex ilLoadL
  310. @subsection Loading from Memory Lumps -- @code{ilLoadL}
  311. @code{DevIL}'s file handling is abstracted to allow loading images from memory called ``lumps''. @code{ilLoadL} handles loading from lumps.
  312. You must specify a valid type as the first parameter and the lump as the second parameter.
  313. The third parameter that @code{ilLoadL} accepts is the total size of the lump.
  314. @code{DevIL} uses this value to perform bounds checking on the input data.
  315. Specify a value of zero for Size if you do not want @code{ilLoadL} to perform any bounds checking.
  316. @subsection Saving to Files
  317. @code{DevIL} also has some powerful saving functions to fully complement the loading functions.
  318. @example
  319. ILboolean ilSaveImage(const char *FileName);
  320. ILboolean ilSave(ILenum Type, const char *FileName);
  321. ILboolean ilSaveF(ILenum Type, ILHANDLE File);
  322. ILuint ilSaveL(ILenum Type, ILvoid *Lump, ILuint Size);
  323. @end example
  324. @code{DevIL}'s saving functions are identical to the loading functions, despite the fact that they save images instead of load images.
  325. Typically, the user does not know exactly how large the output image will be.
  326. If you pass @code{NULL} for @code{Lump} and 0 for @code{Size} to @code{ilSaveL}, @code{ilSaveL} will return the buffer size needed to save an image of @code{Type}.
  327. When a buffer is passed for @code{Lump}, the return value is how many bytes were written to the buffer.
  328. Note that not all formats that have load support have also save support (@pxref{file_formats})
  329. @node Image management
  330. @chapter Image management
  331. @findex ilTexImage
  332. @anchor{ilTexImage reference}
  333. @section Defining Images
  334. @code{ilTexImage} is used to give the current bound image new attributes that you specify.
  335. Any image data or attributes previously in the current bound image are lost after a call to @code{ilTexImage}, so make sure that you call it only after preserving the image data if need be.
  336. @example
  337. ILboolean ilTexImage(ILuint Width, ILuint Height, ILuint Depth, @* ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data);
  338. @end example
  339. @code{ilTexImage} has one of the longer parameter lists of the @code{DevIL} functions, so we will briefly go over what is expected for each argument.
  340. @itemize @minus
  341. @item @code{Width}: The width of the image.
  342. If this is zero, @code{DevIL} creates an image with a width of one.
  343. @item @code{Height}: The height of the image.
  344. If this is zero, @code{DevIL} creates an image with a height of one.
  345. @item @code{Depth}: The depth of the image, if it is an image volume.
  346. Most applications should specify 0 or 1 for this parameter.
  347. @item @code{Bpp}: The bytes per pixel of the image data.
  348. Do not confuse this with bits per pixel, which is also commonly used.
  349. Common bytes per pixel values are 1, 3 and 4.
  350. @item @code{Format}: The format of the image data. @xref{format #defines}, for what you can pass.
  351. @item @code{Type}: The type of image data.
  352. Usually, this will be @code{IL_UNSIGNED_BYTE}, unless you want to utilize multiple bytes per colour channel. @xref{type #defines}, for acceptable type.
  353. @item @code{Data}: Mainly for convenience, if you already have image data loaded and ready to put into the newly created image.
  354. Specifying @code{NULL} for this parameter just results in the image having unpredictable image data.
  355. You can specify image data later using @code{ilSetData} or @code{ilSetPixels}.
  356. @end itemize
  357. @section Getting image data
  358. There are two ways to set image data: one is quick and dirty, while the other is more flexible but slower.
  359. These two functions are @code{ilGetData} and @code{ilCopyPixels}.
  360. @example
  361. ILubyte *ilGetData(ILvoid);
  362. ILuint ilCopyPixels(ILuint XOff, ILuint YOff, ILuint ZOff,
  363. ILuint Width, ILuint Height, ILuint Depth, ILenum Format,
  364. ILenum Type, ILvoid * Data);
  365. @end example
  366. @findex ilGetData
  367. @subsection The Quick Method
  368. Use @code{ilGetData} to get a direct pointer to the current bound image's data pointer.
  369. Do not ever try to delete this pointer that is returned.
  370. To get information about the image data, use @code{ilGetInteger}.
  371. @code{ilGetData} will return @code{NULL} and set an error of @code{IL_ILLEGAL_OPERATION} if there is no currently bound image.
  372. @findex ilCopyPixels
  373. @subsection The Flexible Method
  374. Use @code{ilCopyPixels} to get a portion of the current bound image's data or to get the current image's data with in a different format / type.
  375. @code{DevIL} takes care of all conversions automatically for you to give you the image data in the format or type that you need.
  376. The data block can range from a single line to a rectangle, all the way to a cube.
  377. @code{ilCopyPixels} has a long parameter list, like @code{ilTexImage}, so here is a description of the parameters of @code{ilCopyPixels}:
  378. @itemize @minus
  379. @item @code{XOff}: Specifies where to start copying in the @i{x} direction.
  380. @item @code{YOff}: Specifies where to start copying in the @i{y} direction.
  381. @item @code{ZOff}: Specifies where to start copying in the @i{z} direction.
  382. This will be 0 in most cases, unless you are using image volumes.
  383. @item @code{Width}: Number of pixels to copy in the @i{x} direction.
  384. @item @code{Height}: Number of pixels to copy in the @i{y} direction.
  385. @item @code{Depth}: Number of pixels to copy in the @i{z} direction.
  386. This will be 1, unless
  387. @item @code{Format, Type, Data}: These are basically the same as ones described above. @pxref{ilTexImage reference}.
  388. @end itemize
  389. @section Setting image Data
  390. There are two ways to set image data: one is quick and dirty, while the other is more flexible but slower.
  391. These two functions are @code{ilSetData} and @code{ilSetPixels}.
  392. @example
  393. ILboolean ilSetData(ILvoid *Data);
  394. ILvoid ilSetPixels(ILuint XOff, ILuint YOff, ILuint ZOff,
  395. ILuint Width, ILuint Height, ILuint Depth, ILenum Format,
  396. ILenum Type, ILvoid *Data);
  397. @end example
  398. @findex ilSetData
  399. @subsection The Quick Method
  400. Use @code{ilSetData} to set the image data directly.
  401. @code{DevIL} will copy the data provided in the Data parameter to the image’s data, so you need not worry about @code{DevIL} trying to delete your pointer later on.
  402. This function is the counterpart to @code{ilGetData}.
  403. You must provide image data in the exact same format, type, width, height, depth and bpp as the current bound image, since @code{DevIL} does no conversions here; it just does a simple memory copy.
  404. @code{ilSetData} will return @code{IL_FALSE} and set an error of @code{IL_INVALID_PARAM} if Data is @code{NULL}.
  405. @findex ilSetPixels
  406. @subsection The Flexible Method
  407. Use @code{ilSetPixels} to set a portion of the current bound image’s data or to set the current image’s data with data of a different format / type.
  408. Specify the data block, where you want to put it and what kind of data it is, and @code{DevIL} takes care of all conversions automatically for you.
  409. The data block can range from a single line to a rectangle, all the way to a cube.
  410. @code{ilSetPixels} has a long parameter list, like @code{ilCopyPixels}, so here is a description of the parameters of @code{ilSetPixels}:
  411. @itemize @minus
  412. @item Previous parameters are the same as in @code{ilTexImage}
  413. @item @code{Data}: A pointer to the actual data block. If this is @code{NULL}, @code{DevIL} will set an error of @code{IL_INVALID_PARAM} and return @code{IL_FALSE} (please refer to the section on error handling in @code{DevIL}).
  414. @end itemize
  415. If you specify a combination of an offset with a width/height/depth that makes your data block overreach the edge of the currently bound image, @code{DevIL} will clip your data so that no crashes will occur and that the resulting image will be correctly produced.
  416. @section Copying Images
  417. @code{DevIL} has three functions to copy images: @code{ilCopyImage}, @code{ilOverlayImage} and @code{ilBlit}.
  418. @example
  419. ILboolean ilCopyImage(ILuint Src);
  420. ILboolean ilOverlayImage(ILuint Src, ILint XCoord, ILint YCoord,
  421. ILint ZCoord);
  422. ILboolean ilBlit(ILuint Src, ILint DestX, ILint DestY, ILint DestZ,
  423. ILuint SrcX, ILuint SrcY, ILuint SrcZ, ILuint Width,
  424. ILuint Height, ILuint Depth);
  425. @end example
  426. @findex ilCopyImage
  427. @subsection Direct Copying
  428. Use @code{ilCopyImage} to create a copy of an image. @code{ilCopyImage} will copy the image specified by the image name in Src to the currently bound image. @code{ilCopyImage} can be useful when you want to apply an effect to an image but want to preserve the original.
  429. The image bound before calling @code{ilCopyImage} will still be bound after @code{ilCopyImage} exits.
  430. If you specify an image name in Src that has not been generated by @code{ilGenImages} or @code{ilBindImage}, @code{ilCopyImage} will set the @code{IL_INVALID_PARAM} error and return @code{IL_FALSE}.
  431. @findex ilBlit
  432. @subsection Blitting
  433. @code{ilBlit} copies a portion of an image over to another image.
  434. This is similar to blitting performed in graphics libraries, such as StretchBlt in the Windows API.
  435. You can copy a rectangular block from anywhere in a source image, specified by Src, to any point in the currently bound image.
  436. A description of the various @code{ilBlit} parameters follows:
  437. @itemize @minus
  438. @item @code{Src}: The source image name.
  439. @item @code{DestX}: Specifies where to place the block of image data in the @i{x} direction.
  440. @item @code{DestY}: Specifies where to place the block of image data in the @i{y} direction.
  441. @item @code{DestZ}: Specifies where to place the block of image data in the @i{z} direction.
  442. @item @code{SrcX}: Specifies where to start copying in the @i{x} direction of the source image.
  443. @item @code{SrcY}: Specifies where to start copying in the @i{y} direction of the source image.
  444. @item @code{SrcZ}: Specifies where to start copying in the @i{z} direction of the source image.
  445. @item @code{Width}: How many pixels to copy in the @i{x} direction of the source image.
  446. @item @code{Height}: How many pixels to copy in the @i{y} direction of the source image.
  447. @item @code{Depth}: How many pixels to copy in the @i{z} direction of the source image.
  448. @end itemize
  449. @findex ilOverlay
  450. @subsection Overlaying
  451. @code{ilOverlay} is essentially the same as @code{ilBlit}, but it copies the entire image over, instead of just a portion of the image. @code{ilOverlay} is more of a convenience function, since you can obtain the same results by calling @code{ilBlit} with SrcX, SrcY and SrcZ set to zero, with the Width, Height and Depth parameters set to the source image's height, width and depth, respectively. @code{ilOverlay} is missing six parameters that @code{ilBlit} has:
  452. @itemize @minus
  453. @item @code{Src}: The source image name.
  454. @item @code{DestX}: Specifies where to place the block of image data in the @i{x} direction.
  455. @item @code{DestY}: Specifies where to place the block of image data in the @i{y} direction.
  456. @item @code{DestZ}: Specifies where to place the block of image data in the @i{z} direction.
  457. @end itemize
  458. @subsection Blit/Overlay Behavior
  459. By default, @code{ilBlit} and @code{ilOverlay} will blend the source with the destination image if the source has an alpha channel present.
  460. If you need to blit the image without blending, you can use the @code{IL_BLIT_BLEND} #define.
  461. This behavior can be toggled with @code{ilEnable} and @code{ilDisable}.
  462. @example
  463. ilDisable(IL_BLIT_BLEND); // Turns off blending
  464. ilEnable(IL_BLIT_BLEND); // Turns on blending
  465. @end example
  466. @chapter Image Characteristics
  467. All images have a certain set of characteristics: origin of the image, format of the image, type of the image, and more.
  468. @section Origin
  469. Depending on the file format, data can start in the upper left or the lower left corner of the image.
  470. By default, @code{DevIL} keeps the origin in the same place as the original image.
  471. This can cause your image to be flipped vertically if the image you are loading has an origin other than what you expect.
  472. To obtain the origin of the image, use @code{ilGetInteger}.
  473. @example
  474. ilGetInteger(IL_IMAGE_ORIGIN);
  475. @end example
  476. To force @code{DevIL} to use just one origin, you need to use the following code:
  477. @example
  478. ilEnable(IL_ORIGIN_SET);
  479. ilSetInteger(@emph{Origin});
  480. @end example
  481. @emph{Origin} is either @code{IL_ORIGIN_LOWER_LEFT} or @code{IL_ORIGIN_UPPER_LEFT}. Finally, if you need to find out which origin mode is currently set, use:
  482. @example
  483. ilGetInteger(IL_ORIGIN_MODE);
  484. @end example
  485. @section Format
  486. Format refers to the ordering of the bytes for each pixel.
  487. @anchor{registration}
  488. @section Registration
  489. @node Error handling
  490. @chapter Error handling
  491. @code{DevIL} contains error-handling routines to alert the users of this library to any internal problems in @code{DevIL}.
  492. The @code{ilGetError} function reports all errors in @code{DevIL}. @code{iluErrorString} converts error numbers returned from @code{ilGetError} to a human-readable format.
  493. @example
  494. ILenum ilGetError(ILvoid);
  495. const char* iluErrorString(ILenum Error);
  496. @end example
  497. @findex ilGetError
  498. @section Error Detection
  499. Problems can always occur in any software application, and @code{DevIL} is no different.
  500. @code{DevIL} keeps track of all non-fatal errors that have occurred during its operation.
  501. All errors are kept on a stack maintained by @code{ilGetError}. Every time @code{ilGetError} is called, the last error is returned and pushed off the top of the stack.
  502. You should call @code{ilGetError} until @code{IL_NO_ERROR} is returned. @code{IL_NO_ERROR} signifies that there are no more errors on the error stack.
  503. Most errors reported are not harmful, and @code{DevIL} operation can continue, except for @code{IL_OUT_OF_MEMORY}.
  504. @xref{error_codes}, for error codes that can be returned by @code{ilGetError}.
  505. @findex iluErrorString
  506. @section Error Strings
  507. @code{iluErrorString} returns a human readable error string from any error that @code{ilGetError} can return.
  508. This is useful for when you want to display what kind of error happened to the user.
  509. @subsection Languages
  510. The ILU error messages have been translated into multiple languages:
  511. Arabic, Dutch, German, Japanese and Spanish.
  512. The default language is English.
  513. @subsection Selecting a Language
  514. @code{iluSetLanguage} will change the error string returned by @code{iluErrorString} to the language specified in its parameter.
  515. Languages supported are: English, Arabic, Dutch, German, Japanese and Spanish.
  516. @xref{language #defines}, for a list of possible values.
  517. Be aware that if the Unicode version of @code{DevIL} is not being used, some translations will not display properly.
  518. An example is Arabic, which uses characters outside of the standard ASCII character set.
  519. @node Image manipulation
  520. @chapter Image manipulation
  521. ILU (Image Library Utilities) contains functions to manipulate any type of image in a variety of ways.
  522. Some functions filter images, while others perform a wider variety of operations, such as scaling an image.
  523. This section will give a comparison of the utility functions against the below figure.
  524. @float Figure,fig:stairway_original
  525. @center @image{images/original_stairway,14cm}
  526. @caption{Original, unmodified image}
  527. @end float
  528. This is a crop of a Bertrand Benoit's image taken from @url{http://www.blender.org/features-gallery/gallery/art-gallery/,Blender art gallery}, and Bertrand has kindly allowed us to use it for demonstrations.
  529. You can check out his @url{http://www.bertrand-benoit.com,website}.
  530. Thank you, Bertrand!
  531. The image samples here have a better-than-bad resolution, so you don't have to be afraid to zoom at them if you wish to see details.
  532. @findex iluAlienify
  533. @section Alienifying
  534. @code{iluAlienify} is a filter I created purely by accident, when I was attempting to write colour matrix code.
  535. The effect @code{iluAlienify} gives to an image is a green and purple tint.
  536. On images with humans in them, @code{iluAlienify} generally makes the people look green, hence the fabricated term ``alienify''.
  537. @code{iluAlienify} does not accept any parameters.
  538. The figure below illustrates this effect on the @code{DevIL} logo.
  539. @float Figure,fig:stairway_alienified
  540. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_alienify,4.9cm}
  541. @caption{Original and ``alienified'' image}
  542. @end float
  543. @findex iluBlurAverage
  544. @findex iluBlurGaussian
  545. @section Blurring
  546. ILU has two blurring functions – @code{iluBlurAverage} and @code{iluBlurGaussian}. Blurring can be used for a simple motion blur effect or something as sophisticated as concealing the identity of a person in an image.
  547. Both of these functions use a convolution filter and multiple iterations to blur an image.
  548. Gaussian blurs look more natural than averaging blurs, because the center pixel in the convolution filter ``weighs'' more.
  549. For an in-depth description of convolution filters, see the excellent @emph{Elementary Digital Filtering} article at @url{http://www.gamedev.net/reference/programming/features/edf/,gamedev.net}.
  550. @code{iluBlurAverage} and @code{iluBlurGaussian} are functionally equivalent.
  551. Both functions accept a single parameter.
  552. Call the desired function with the number of iterations of blurring you wish to be performed on the image.
  553. Increase the number of iterations to increase the blurriness of an image.
  554. @float Figure,fig:stairway_blurred
  555. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_blurAvg_10,4.9cm} @ @image{images/ilu_small_stairway_blurGaussian_10,4.9cm}
  556. @caption{Original image, average blurred and gaussian blurred, both with 10 iterations applied}
  557. @end float
  558. @findex iluContrast
  559. @section Contrast
  560. ILU can apply more colour contrast to your image by brightening the lights and darkening the darks via @code{iluContrast}. This effect can make a dull image livelier and ``stand out'' more.
  561. @code{iluContrast} accepts a single parameter describing the desired amount of contrast to modify the image by.
  562. @itemize
  563. @item values from 0.0 to 1.0 decrease the amount of contrast in the image.
  564. @item value of 1.0 does not affect the image.
  565. @item values above 1.0 to 1.7 increase the amount of contrast in the image, with 1.7 increasing the contrast the most.
  566. @item values outside of the 0.0 to 1.7 range will give undefined results. -0.5 to 0.0 will actually create a negative of the image and increase the contrast.
  567. @end itemize
  568. @float Figure,fig:stairway_contrast
  569. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_contrast_0.4,4.9cm} @ @image{images/ilu_small_stairway_contrast_1.7,4.9cm}
  570. @caption{Original image, image with contrast of 0.4 and with contrast of 1.7}
  571. @end float
  572. @findex iluEqualize
  573. @section Equalization
  574. Sometimes it may be useful to equalize an image – that is, bring the extreme colour values to a median point.
  575. @code{iluEqualize} darkens the bright colours and lightens the dark colours, reducing the contrast in an image or ``equalizing'' it.
  576. The below figure shows the results of applying @code{iluEqualize} to the @code{DevIL} image.
  577. @float Figure,fig:stairway_equalized
  578. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_equalize,4.9cm}
  579. @caption{Original image and equalized image}
  580. @end float
  581. @findex iluGammaCorrect
  582. @section Gamma Correction
  583. @code{iluGammaCorrect} applies gamma correction to an image using an exponential curve.
  584. The single parameter @code{iluGammaCorrect} accepts is the gamma correction factor you wish to use.
  585. A gamma correction factor of 1.0 leaves the image unmodified.
  586. Values in the range @code{0.0 - 1.0} darken the image.
  587. 0.0 leaves a totally black image.
  588. Anything above 1.0 brightens the image, but values too large may saturate the image.
  589. @float Figure,fig:stairway_gamma
  590. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_gammaCorrect_0.7,4.9cm} @ @image{images/ilu_small_stairway_gammaCorrect_1.6,4.9cm}
  591. @caption{Original image, image with gamma 0.7 and with with gamma 1.6}
  592. @end float
  593. @findex iluNegative
  594. @section Negativity
  595. @code{iluNegative} is a very basic function that inverts every pixel's colour in an image.
  596. For example, pure white becomes pure black, and vice-versa.
  597. The resulting colour of a pixel can be determined by this formula: @code{new_colour = ~old_colour} (where the tilde is the negation of the set of bits).
  598. @code{iluNegative} does not accept any parameters and is reversible by calling it again.
  599. @float Figure,fig:stairway_negative
  600. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_negative,4.9cm}
  601. @caption{Original and negative image}
  602. @end float
  603. @findex iluNoisify
  604. @section Noise
  605. ILU can add ``random'' noise to any image to make it appear noisy.
  606. The function, @code{iluNoisify}, simply uses the standard libc @code{rand} function after initializing it with a seed to @code{srand}. If your program depends on a different seed to @code{rand}, reset it after calling @code{iluNoisify}. The seed ILU uses is the standard @code{time(NULL)} call.
  607. Of course, the noise added to the image is not totally random, since no such thing exists, but there should be no repeating, except in extremely large images.
  608. @float Figure,fig:stairway_noisify
  609. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_noisify_0.1,4.9cm} @ @image{images/ilu_small_stairway_noisify_0.8,4.9cm}
  610. @caption{Original image, noisified image 0.1, noisified 0.8}
  611. @end float
  612. @code{iluNoisify} accepts a single parameter – the tolerance to use.
  613. This parameter is a clamped (float) value that should be in the range @code{0.0f - 1.0f}.
  614. Lower values indicate a lower tolerance, while higher values indicate the opposite.
  615. The tolerance indicates just how much of a mono intensity that @code{iluNoisify} is allowed to apply to each pixel.
  616. A ``random'' mono intensity is applied to each pixel so that you will not end up with totally new colours, just the same colours with a different luminance value.
  617. Colours change by both negative and positive values, so some pixels may be darker, some may be lighter, and others will remain the same.
  618. @findex iluPixelize
  619. @section Pixelization
  620. @code{iluPixelize} creates pixelized images by averaging the colour values of blocks of pixels.
  621. The single parameter passed to @code{iluPixelize} determines the size of these square blocks.
  622. The result is a pixelized image.
  623. Call @code{iluPixelize} with values greater than 1 to pixelize the image.
  624. The larger the values, the larger the pixel blocks will be.
  625. A value of 1 will leave the image unchanged.
  626. Values less than 1 generate an error.
  627. @float Figure,fig:stairway_pixelize
  628. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_pixelize_5,4.9cm}
  629. @caption{Pixelization of 5 pixels across}
  630. @end float
  631. @findex iluSharpen
  632. @section Sharpening
  633. Sharpening sharply defines the outlines in an image. @code{iluSharpen} performs this sharpening effect on an image.
  634. @code{iluSharpen} accepts two parameters: the sharpening factor and the number of iterations to perform the sharpening effect.
  635. The sharpening factor must be in the range of 0.0 - 2.5.
  636. @itemize
  637. @item values from 0.0 to 1.0 do a type of reverse sharpening, blurring the image.
  638. @item value of 1.0 for the sharpening factor will have no effect on the image.
  639. @item values in the range 1.0 - 2.5 will sharpen the image, with 2.5 having the most pronounced sharpening effect.
  640. @item values outside of the 0.0 - 2.5 range produce undefined results.
  641. @end itemize
  642. The number of iterations to perform will usually be 1, but to achieve more sharpening, increase the number of iterations.
  643. This parameter is similar to the @emph{Iterations} parameter of the two blurring functions.
  644. The time it takes to run this function is directly proportional to the number of iterations desired.
  645. @float Figure,fig:stairway_sharpen
  646. @center @image{images/small_stairway,4.9cm} @ @image{images/ilu_small_stairway_sharpen_1.8_2,4.9cm} @ @image{images/ilu_small_stairway_sharpen_2.1_3,4.9cm}
  647. @caption{Original image, image sharpened by 1.8 in 2 iterations and sharpened by 2.1 in 3 iterations}
  648. @end float
  649. @c @node Resizing Images
  650. @chapter Resizing Images
  651. @findex iluScale
  652. @section Basic Scaling
  653. To resize images, use the @code{iluScale} function:
  654. @example
  655. ILboolean iluScale(ILuint Width, ILuint Height, ILuint Depth);
  656. @end example
  657. The three parameters are relatively explanatory.
  658. Any image can be resized to a new width, height and depth, provided that you have enough memory to hold the new image.
  659. The new dimensions do not have to be the same as the original in any way.
  660. Aspect ratios of the image do not even have to be the same.
  661. The currently bound image is replaced entirely by the new scaled image.
  662. If you specify a dimension greater than the original dimension, the image enlarges in that direction.
  663. Alternately, if you specify a dimension smaller than the original dimension, the image shrinks in that direction.
  664. @c @multitable {Original image} { } {@image{images/manipulation/enlarged}} { } {Shrunk image}
  665. @c @item @image{images/manipulation/resize-original} @tab @tab @image{images/manipulation/enlarged} @c @tab @tab @image{images/manipulation/shrunk}
  666. @c @item @emph{Original image} @tab @tab @emph{Enlarged image} @tab @tab @emph{Shrunk image}
  667. @c @end multitable
  668. @findex iluImageParameter
  669. @section Advanced Scaling
  670. ILU also allows you to specify which method you want to use to resize images.
  671. As you can see in the middle figure above, the enlarged image is very pixelized.
  672. The shrunk image is also blocky.
  673. This is because a nearest filter was applied to the image in figure 5.1 to produce figures 5.2 and 5.3.
  674. ILU allows you to use different filters to produce better scaling results via @code{iluImageParameter}:
  675. @itemize @bullet
  676. @item Nearest filter - @code{ILU_NEAREST}
  677. @item Linear filter - @code{ILU_LINEAR}
  678. @item Bilinear filter - @code{ILU_BILINEAR}
  679. @item Box filter - @code{ILU_SCALE_BOX}
  680. @item Triangle filter - @code{ILU_SCALE_TRIANGLE}
  681. @item Bell filter - @code{ILU_SCALE_BELL}
  682. @item B Spline filter - @code{ILU_SCALE_BSPLINE}
  683. @item Lanczos filter - @code{ILU_SCALE_LANCZOS3}
  684. @item Mitchell filter - @code{ILU_SCALE_MITCHELL}
  685. @end itemize
  686. Just use the @code{ILU_FILTER} define as @emph{PName} in @code{iluImageParameter} with the appropriate filter define as @emph{Param}.
  687. @example
  688. ILvoid iluImageParameter(ILenum PName, ILenum Param);
  689. @end example
  690. @section Filter Comparisons
  691. The first three filters (nearest, linear and bilinear) require an increasing amount of time to resize an image, with nearest being the quickest and bilinear being the slowest of the three.
  692. All the filters after bilinear are considered the “advanced” scaling functions and require much more time to complete, but they generally produce much nicer results.
  693. When minimizing an image, bilinear filtering should be sufficient, since it uses a four-pixel averaging scheme to create every destination pixel.
  694. Minimized images do not generally have to use higher sampling schemes to achieve a reasonable image.
  695. Enlarging an image, though, depends quite heavily on how good the sampling scheme is.
  696. ILU provides several filtering functions to let you choose which one best fits your needs: speed versus image quality.
  697. Below is a comparison of the different types of filters when enlarging an image.
  698. @c @multitable {@image{images/lena/nearest}} { } {@image{images/lena/nearest}} { } {@image{images/lena/nearest}}
  699. @c @item @image{images/lena/nearest} Nearest filter
  700. @c @tab @tab @image{images/lena/linear} Linear filter
  701. @c @tab @tab @image{images/lena/bilinear} Bilinear filter
  702. @c @item @image{images/lena/box} Box filter
  703. @c @tab @tab @image{images/lena/triangle} Triangle filter
  704. @c @tab @tab @image{images/lena/bell} Bell filter
  705. @c @item @image{images/lena/bspline} B spline filter
  706. @c @tab @tab @image{images/lena/lanczos} Lanczos filter
  707. @c @tab @tab @image{images/lena/mitchell} Mitchell filter
  708. @c @end multitable
  709. @c @node Sub-Images
  710. @chapter Sub-Images
  711. @section Mipmaps
  712. Mipmaps in @code{DevIL} are successive half-dimensioned power-of-2 images.
  713. The dimensions do not have to be powers of 2 if you generate them manually, but @code{DevIL}'s mipmap generation facilities assume power-of-2 images.
  714. @c @multitable {@image{images/mipmaps/128}} {@image{images/mipmaps/64}} {@image{images/mipmaps/32}} {@image{images/mipmaps/16}} {@image{images/mipmaps/8}} {@image{images/mipmaps/4}} {@image{images/mipmaps/2}} {@image{images/mipmaps/1}}
  715. @c @item @image{images/mipmaps/128}
  716. @c @tab @image{images/mipmaps/64}
  717. @c @c @tab @image{images/mipmaps/32}
  718. @c @tab @image{images/mipmaps/16}
  719. @c @tab @image{images/mipmaps/8}
  720. @c @tab @image{images/mipmaps/4}
  721. @c @tab @image{images/mipmaps/2}
  722. @c @tab @image{images/mipmaps/1}
  723. @c @end multitable
  724. @center @emph{All mipmap levels down to 1x1}
  725. @findex iluBuildMipmaps
  726. @subsection Mipmap Creation
  727. You generate mipmaps for any image using @code{iluBuildMipmaps}. If the image already has mipmaps, the previous mipmaps are erased, and new mipmaps are generated.
  728. Otherwise, @code{iluBuildMipmaps} generates mipmaps for the image.
  729. The mipmaps built are always powers of 2.
  730. If the original image does not have power-of-2 dimensions, @code{iluBuildMipmaps} resizes the original image via @code{iluScale} to have power-of-2 dimensions.
  731. @findex iluActiveMipmap
  732. @subsection Mipmap Access
  733. Access mipmaps through the @code{iluActiveMipmap} function:
  734. @example
  735. ILboolean ilActiveMipmap(ILuint MipNum);
  736. @end example
  737. @code{iluActiveMipmap} sets the current image to the @emph{MipNum} mipmap level of the current image.
  738. If there are no mipmaps present, then @code{iluActiveMipmap} returns @code{IL_FALSE}, else it returns @code{IL_TRUE}. The base image is mipmap level 0, so specify 0 for @emph{MipNum} to return to the base image.
  739. The only other method for setting the current image to the base image is to call @code{ilBindImage} again.
  740. @section Animations
  741. Animations are similar to mipmaps, but instead of being smaller successive images, the images are the same size but have different data.
  742. The successive animation chains in @code{DevIL} can be used to create animations in your programs.
  743. File formats that natively support animations are @code{.gif} and @code{.mng}.
  744. You can also create your own sub-images as animations.
  745. @subsection Animation Chain Creation
  746. To be added...
  747. @subsection Animation Chain Access
  748. Access animations through the @code{iluActiveImage} function:
  749. @example
  750. ILboolean ilActiveImage(ILuint ImageNum);
  751. @end example
  752. @code{iluActiveImage} sets the current image to the @emph{ImageNum} animation frame of the current image.
  753. If there are no animation frames present, then @code{iluActiveImage} returns @code{IL_FALSE}, else it returns @code{IL_TRUE}. The base image is animation frame 0, so specify 0 for @emph{ImageNum} to return to the base image.
  754. The only other method for setting the current image to the base image is to call @code{ilBindImage} again.
  755. @code{iluActiveImage} is functionally equivalent to @code{iluActiveMipmap}, except that it deals with animations and not mipmaps.
  756. @section Layers
  757. @code{DevIL} does not have a full layer implementation yet.
  758. @section Sub-Image Mixing
  759. An image can have both mipmaps and animations at the same time.
  760. Every image in an animation chain can have its own set of mipmaps, though it is not necessary by any means.
  761. If you ``activate'' an animation image in the base image's animation chain, the active image becomes the new ``base'' image.
  762. Therefore, if you call @code{iluActiveMipmap} after @code{iluActiveImage}, a mipmap from the selected image in the animation chain is chosen.
  763. @c @node DXTC/S3TC Notes
  764. @chapter DXTC/S3TC Notes
  765. @section DDS Loading/Saving
  766. @code{DevIL} supports loading and saving of Microsoft .dds files.
  767. DDS files can either be compressed or uncompressed.
  768. If they are compressed, DDS files use DirectX Texture Compression (DXTC). DXTC is also known as S3TC, since Microsoft licensed the compression technology from S3.
  769. @subsection Keeping DXTC Data
  770. When loading, @code{DevIL} uncompresses the DXTC.
  771. If you call @code{ilEnable} with the @code{IL_KEEP_DXTC_DATA} parameter, @code{DevIL} will keep an uncompressed copy of the DXTC data along with the image.
  772. Functions that deal with DXTC data can use this data without having to recompress the uncompressed data, making these functions operate faster.
  773. The only drawback is the use of more memory.
  774. @subsection Controlling Saving
  775. @code{DevIL}'s DXTC support consists of three different compression formats: DXT1, DXT3 and DXT5.
  776. DXT2 and DXT4 use premultiplied alpha, which not even OpenGL supports.
  777. @code{DevIL} loads DXT2 and DXT4 textures but immediately converts them to formats that do not use premultiplied alpha.
  778. To set what format to save DDS files in, use this line:
  779. @example
  780. ilSetInteger(IL_DXTC_FORMAT, Format);
  781. @end example
  782. @emph{Format} can be @code{IL_DXT1}, @code{IL_DXT3} or @code{IL_DXT5}.
  783. @subsection Compression Method
  784. @code{DevIL} can use the nVidia Texture Tools (NVTT) library, the libsquish library and its own internal compressor to generate DXTC data.
  785. By default, @code{DevIL} uses its internal compressor.
  786. This compressor is fast but is not very high quality.
  787. NVTT is usually CUDA-enabled, meaning that it can run quickly on computers with GeForce 8-series and higher cards.
  788. libsquish generates images with the highest quality possible, but it can be very slow.
  789. To enable compression by NVTT or libsquish, use one of the following lines of code:
  790. @example
  791. ilEnable(IL_NVIDIA_COMPRESS);
  792. ilEnable(IL_SQUISH_COMPRESS);
  793. @end example
  794. You can also disable compression by these libraries by using @code{ilDisable}.
  795. If both are enabled, NVTT is used.
  796. @section Retrieving DXTC Data
  797. To retrieve a copy of the DXTC data, use @code{ilGetDXTCData}.
  798. To determine how large Buffer should be, first call @code{ilGetDXTCData} with the Buffer parameter as @code{NULL}.
  799. This function will then return the number of bytes that are required to completely store the DXTC data.
  800. Call it a second time to actually retrieve the data.
  801. @example
  802. ILuint ilGetDXTCData(ILvoid *Buffer, ILuint BufferSize,
  803. ILenum DXTCFormat);
  804. @end example
  805. If the DXTC data does not exist in the format that you request, @code{DevIL} will automatically compress the data.
  806. If @code{ilGetDXTCData} returns 0, then the data could not be compressed.
  807. To see if a certain format of DXTC data already exists for the currently bound image, call @code{ilGetInteger} with the @code{IL_DXTC_DATA_FORMAT} parameter.
  808. @section Compressing DXTC Data
  809. In the previous section, it was mentioned that @code{DevIL} can compress the data of an image with DXT compression. If you have image data in your program that you want to compress, you can use the @code{ilCompressDXT} function.
  810. @example
  811. ILubyte *ilCompressDXT(ILubyte *Data, ILuint Width, ILuint Height,
  812. ILuint Depth, ILenum DXTCFormat, ILuint *DXTCSize);
  813. @end example
  814. Data must be in BGRA format for NVTT and @code{DevIL}'s compressor, and it must be in RGBA format for libsquish. Please keep this in mind when calling this @code{ilCompressDXT}. Look at Compression Method in this section for information on how to use these libraries.
  815. @section OpenGL/Direct3D DXTC Support
  816. ILUT allows you to directly send the DXTC data to OpenGL or Direct3D.
  817. Several modes in ILUT directly control this behavior.
  818. @subsection OpenGL S3TC Support
  819. OpenGL can use S3TC (DXTC) textures via extensions.
  820. If a computer does not support the S3TC texture extension, @code{DevIL} will just send the data normally through @code{glTexImage2D}, as always.
  821. Please keep in mind that DDS files store their data in a top-down format, so if you enable the OpenGL S3TC support, make certain to set the origins of all images in the upper left:
  822. @example
  823. ilEnable(IL_ORIGIN_SET);
  824. ilSetInteger(IL_ORIGIN_MODE, IL_ORIGIN_UPPER_LEFT);
  825. @end example
  826. To enable the OpenGL S3TC support, use the @code{ilutEnable} function with the @code{ILUT_GL_USE_S3TC} parameter:
  827. @example
  828. ilutEnable(ILUT_GL_USE_S3TC);
  829. @end example
  830. Setting this parameter means that ILUT will only use DXTC data from images that are already compressed with DXTC (e.g.
  831. DDS files). To force ILUT to compress any image it sends to OpenGL, use @code{ilutEnable} again:
  832. @example
  833. ilutEnable(ILUT_GL_GEN_S3TC);
  834. @end example
  835. This can adversely affect your performance while loading textures, though, so use it with caution, especially if you are running a performance-critical application.
  836. @subsection Direct3D DXTC Support
  837. ILUT's Direct3D (D3D) support works exactly like the OpenGL support, except you use the @code{ILUT_D3D_USE_DXTC} and @code{ILUT_D3D_GEN_DXTC} defines instead of @code{ILUT_GL_USE_S3TC} and @code{ILUT_GL_GEN_S3TC}, respectively.
  838. @node Common #defines
  839. @appendix Common @code{DevIL} @code{#defines}
  840. Here goes lists of @code{DevIL} @code{#defines} used in functions that manipulate image data.
  841. As you can see, they are self-explanatory.
  842. @anchor{format #defines}
  843. @section @code{format}-related @code{#defines}
  844. @itemize @w{ }
  845. @item @code{IL_COLOUR_INDEX}
  846. @item @code{IL_RGB}
  847. @item @code{IL_RGBA}
  848. @item @code{IL_BGR}
  849. @item @code{IL_BGRA}
  850. @item @code{IL_LUMINANCE}
  851. @end itemize
  852. @anchor{type #defines}
  853. @section @code{type}-related @code{#defines}
  854. @itemize @w{ }
  855. @item @code{IL_BYTE}
  856. @item @code{IL_UNSIGNED_BYTE}
  857. @item @code{IL_SHORT}
  858. @item @code{IL_UNSIGNED_SHORT}
  859. @item @code{IL_INT}
  860. @item @code{IL_UNSIGNED_INT}
  861. @item @code{IL_FLOAT}
  862. @item @code{IL_DOUBLE}
  863. @end itemize
  864. @anchor{language #defines}
  865. @section Language-related @code{#defines}
  866. @itemize @w{ }
  867. @item @code{IL_ENGLISH}
  868. @item @code{IL_ARABIC}
  869. @item @code{IL_DUTCH}
  870. @item @code{IL_GERMAN}
  871. @item @code{IL_JAPANESE}
  872. @item @code{IL_SPANISH}
  873. @end itemize
  874. @anchor{error_codes}
  875. @appendix Common @code{DevIL} Error Codes
  876. Errors sometimes occur within @code{DevIL}.
  877. To get the error code of the last error that occurred, call @code{ilGetError} with no parameters.
  878. To get a human-readable string of an error code, call @code{iluErrorString} with the error code.
  879. A table of error codes follows:
  880. @multitable {IL_FORMAT_NOT_SUPPORTED} {0x503} {1283}
  881. @headitem Error code @code{#define} @tab Hex value @tab Decimal value
  882. @item @code{IL_NO_ERROR} @tab @code{0x000} @tab @code{0}
  883. @item @code{IL_INVALID_ENUM} @tab @code{0x501} @tab @code{1281}
  884. @item @code{IL_OUT_OF_MEMORY} @tab @code{0x502} @tab @code{1282}
  885. @item @code{IL_FORMAT_NOT_SUPPORTED} @tab @code{0x503} @tab @code{1283}
  886. @item @code{IL_INTERNAL_ERROR} @tab @code{0x504} @tab @code{1284}
  887. @item @code{IL_INVALID_VALUE} @tab @code{0x505} @tab @code{1285}
  888. @item @code{IL_ILLEGAL_OPERATION} @tab @code{0x506} @tab @code{1286}
  889. @item @code{IL_ILLEGAL_FILE_VALUE} @tab @code{0x507} @tab @code{1287}
  890. @item @code{IL_INVALID_FILE_HEADER} @tab @code{0x508} @tab @code{1288}
  891. @item @code{IL_INVALID_PARAM} @tab @code{0x509} @tab @code{1289}
  892. @item @code{IL_COULD_NOT_OPEN_FILE} @tab @code{0x50A} @tab @code{1290}
  893. @item @code{IL_INVALID_EXTENSION} @tab @code{0x50B} @tab @code{1291}
  894. @item @code{IL_FILE_ALREADY_EXISTS} @tab @code{0x50C} @tab @code{1292}
  895. @item @code{IL_OUT_FORMAT_SAME} @tab @code{0x50D} @tab @code{1293}
  896. @item @code{IL_STACK_OVERFLOW} @tab @code{0x50E} @tab @code{1294}
  897. @item @code{IL_STACK_UNDERFLOW} @tab @code{0x50F} @tab @code{1295}
  898. @item @code{IL_INVALID_CONVERSION} @tab @code{0x510} @tab @code{1296}
  899. @item @code{IL_BAD_DIMENSIONS} @tab @code{0x511} @tab @code{1297}
  900. @item @code{IL_FILE_READ_ERROR} @tab @code{0x512} @tab @code{1298}
  901. @item @code{IL_LIB_JPEG_ERROR} @tab @code{0x5E2} @tab @code{1506}
  902. @item @code{IL_LIB_PNG_ERROR} @tab @code{0x5E3} @tab @code{1507}
  903. @item @code{IL_LIB_TIFF_ERROR} @tab @code{0x5E4} @tab @code{1508}
  904. @item @code{IL_LIB_MNG_ERROR} @tab @code{0x5E5} @tab @code{1509}
  905. @item @code{IL_LIB_JP2_ERROR} @tab @code{0x5E6} @tab @code{1510}
  906. @item @code{IL_LIB_EXR_ERROR} @tab @code{0x5E7} @tab @code{1511}
  907. @item @code{IL_UNKNOWN_ERROR} @tab @code{0x5FF} @tab @code{1535}
  908. @end multitable
  909. @anchor{file_formats}
  910. @appendix Supported File Formats
  911. @code{DevIL} supports loading and saving of a large number of image formats.
  912. Table lists the formats @code{DevIL} supports sorted according to @code{#define}.
  913. @c The page should fit into margins since somebody may want to print it...
  914. @multitable {Graphics Interchange Format} {.pbm, .pgm, } {IL_DOOM_FLAT} {loading?} {saving?}
  915. @headitem Format name @tab Extension @tab IL @code{#define} @tab Loading? @tab Saving?
  916. @item Blizzard texture @tab .blp @tab @code{IL_BLP} @tab yes @tab no
  917. @item Windows bitmap @tab .bmp @tab @code{IL_BMP} @tab yes @tab yes
  918. @item C-style header @tab .h @tab @code{IL_CHED} @tab no @tab yes
  919. @item Dr. Halo Cut File @tab .cut @tab @code{IL_CUT} @tab yes @tab no
  920. @item ZSoft Multi-PCX @tab .dcx @tab @code{IL_DCX} @tab yes @tab no
  921. @item Digital Imaging and Communications in Medicine @tab .dicom, .dcm @tab @code{IL_DCM} @tab yes @tab no
  922. @item DirectDraw surface @tab .dds @tab @code{IL_DDS} @tab yes @tab yes
  923. @item Digital Picture Exchange @tab .dpx @tab @code{IL_DPX} @tab yes @tab no
  924. @item DOOM walls/flats @tab .lmp @tab @code{IL_DOOM}, @code{IL_DOOM_FLAT} @tab yes @tab no
  925. @item OpenEXR @tab .exr @tab @code{IL_EXR} @tab yes @tab yes
  926. @item Flexible Image Transport System @tab .fits, .fit @tab @code{IL_FITS} @tab yes @tab no
  927. @item Heavy Metal: FAKK 2 Texture @tab .ftx @tab @code{IL_FTX} @tab yes @tab no
  928. @item Graphics Interchange Format @tab .gif @tab @code{IL_GIF} @tab yes @tab no
  929. @item Radiance High Dynamic Range @tab .hdr @tab @code{IL_HDR} @tab yes @tab yes
  930. @item Macintosh Icons @tab .icns @tab @code{IL_ICNS} @tab yes @tab no
  931. @item Windows Icons @tab .ico, .cur @tab @code{IL_ICO} @tab yes @tab no
  932. @item Interchange File Format @tab .iff @tab @code{IL_IFF} @tab yes @tab no
  933. @item Infinity Ward Image @tab .iwi @tab @code{IL_IWI} @tab yes @tab no
  934. @item Jpeg Network Graphics @tab .jng @tab @code{IL_JNG} @tab yes @tab no
  935. @item Jpeg 2000 @tab .jp2 @tab @code{IL_JP2} @tab yes @tab yes
  936. @item Jpeg @tab .jpg, .jpe, .jpeg @tab @code{IL_JPG} @tab yes @tab yes
  937. @item Interlaced Bitmap @tab .lbm @tab @code{IL_LBM} @tab yes @tab no
  938. @item Homeworld File @tab .lif @tab @code{IL_LIF} @tab yes @tab no
  939. @item Half-Life Model @tab .mdl @tab @code{IL_MDL} @tab yes @tab no
  940. @item Mng Animation @tab .mng @tab @code{IL_MNG} @tab yes @tab no
  941. @item MPEG-1 Audio Layer 3 @tab .mp3 @tab @code{IL_MP3} @tab yes @tab no
  942. @item PhotoCD @tab .pcd @tab @code{IL_PCD} @tab yes @tab no
  943. @item ZSoft PCX @tab .pcx @tab @code{IL_PCX} @tab yes @tab yes
  944. @item Softimage PIC @tab .pic @tab @code{IL_PIC} @tab yes @tab no
  945. @item PIX @tab .pix @tab @code{IL_PIX} @tab yes @tab no
  946. @item Portable Network Graphics @tab .png @tab @code{IL_PNG} @tab yes @tab yes
  947. @item Pnm @tab .pbm, .pgm, .ppm, .pnm @tab @code{IL_PPM} @tab yes @tab yes
  948. @item Adobe PhotoShop @tab .psd @tab @code{IL_PSD} @tab yes @tab yes
  949. @item PaintShop Pro @tab .psp @tab @code{IL_PSP} @tab yes @tab no
  950. @item Pixar @tab .pxr @tab @code{IL_PXR} @tab yes @tab no
  951. @item Raw Data @tab * @tab @code{IL_RAW} @tab yes @tab yes
  952. @item Homeworld 2 Texture @tab .rot @tab @code{IL_ROT} @tab yes @tab no
  953. @item Silicon Graphics @tab .sgi, .bw, .rgb, .rgba @tab @code{IL_SGI} @tab yes @tab yes
  954. @item Sun RAS @tab .sun, .ras, .rs, .im* @tab @code{IL_SUN} @tab yes @tab no
  955. @item Creative Assembly Texture @tab .texture @tab @code{IL_TEXTURE} @tab yes @tab no
  956. @item Targa @tab .tga @tab @code{IL_TGA} @tab yes @tab yes
  957. @item Tagged Image File Format @tab .tif, .tiff @tab @code{IL_TIF} @tab yes @tab yes
  958. @item Gamecube Texture @tab .tpl @tab @code{IL_TPL} @tab yes @tab no
  959. @item Unreal Texture @tab .utx @tab @code{IL_UTX} @tab yes @tab no
  960. @item Valve Texture @tab .vtf @tab @code{IL_VTF} @tab yes @tab yes
  961. @item Quake2 Texture @tab .wal @tab @code{IL_WAL} @tab yes @tab no
  962. @item HD Photo @tab .wdp, .hdp @tab @code{IL_WDP} @tab yes @tab no
  963. @item X Pixel Map @tab .xpm @tab @code{IL_XPM} @tab yes @tab no
  964. @end multitable
  965. @strong{Exception:} @code{IL_JPG} (IJL) type is not supported by @code{ilLoadF} nor by @code{ilSaveF}. @code{IL_JPG} (libjpeg) is supported by both.
  966. @node Sample program
  967. @appendix Sample @code{DevIL} program
  968. If you are not used to this approach, you may be grateful for a short program demonstrating how to actually use @code{DevIL}:
  969. @c Generator: GNU source-highlight, by Lorenzo Bettini, http://www.gnu.org/software/src-highlite
  970. @example
  971. @b{#include}@t{<IL/il.h>}
  972. @b{#include}@t{<stdlib.h>} @i{/* because of malloc() etc. */}
  973. int @b{main}(int argc, const char * argv[])
  974. @{
  975. ILuint handle, w, h;
  976. @i{/* First we initialize the library. */}
  977. @i{/*Do not forget that... */}
  978. @b{ilInit}();
  979. @i{/* We want all images to be loaded in a consistent manner */}
  980. @b{ilEnable}(IL_ORIGIN_SET);
  981. @i{/* In the next section, we load one image */}
  982. @b{ilGenImages}(1, & handle);
  983. @b{ilBindImage}(handle);
  984. ILboolean loaded = @b{ilLoadImage}(@t{"original_file.jpg"});
  985. if (loaded == IL_FALSE)
  986. return -1; @i{/* error encountered during loading */}
  987. @i{/* Let's spy on it a little bit */}
  988. w = @b{ilGetInteger}(IL_IMAGE_WIDTH); @i{// getting image width}
  989. h = @b{ilGetInteger}(IL_IMAGE_HEIGHT); @i{// and height}
  990. @b{printf}(@t{"Our image resolution: %dx%d}@t{\n}@t{"}, w, h);
  991. @i{/* how much memory will we need? */}
  992. int memory_needed = w * h * 3 * @b{sizeof}(unsigned char);
  993. @i{/* We multiply by 3 here because we want 3 components per pixel */}
  994. ILubyte * data = (ILubyte *)@b{malloc}(memory_needed);
  995. @i{/* finally get the image data */}
  996. @b{ilCopyPixels}(0, 0, 0, w, h, 1, IL_RGB, IL_UNSIGNED_BYTE, data);
  997. @i{/* We want to do something with the image, right? */}
  998. int i;
  999. for(i = 0; i < memory_needed; i++)
  1000. if(i % 31 == 0) @i{/* vandalise the image */}
  1001. data[i] = i % 255;
  1002. @i{/* And maybe we want to save that all... */}
  1003. @b{ilSetPixels}(0, 0, 0, w, h, 1, IL_RGB, IL_UNSIGNED_BYTE, data);
  1004. @i{/* and dump them to the disc... */}
  1005. @b{ilSaveImage}(@t{"our_result.png"});
  1006. @i{/* Finally, clean the mess! */}
  1007. @b{ilDeleteImages}(1, & handle);
  1008. @b{free}(data); data = NULL;
  1009. @b{return} 0;
  1010. @}
  1011. @end example
  1012. @node Functions index
  1013. @unnumbered Functions index
  1014. @printindex fn
  1015. @bye