Open Image Library Readme, Notes and Quick Use
----------------------------------------------
<grosse> If God had wanted us to use open source, he would've given humans GNU public licenses.

All basic types used in this library are taken from OpenGL, defined in gl/gl.h.  We thought it best to not define our own cross-platform types, which could cause some confusion and was deemed unnecessary.


As defined in il.h, the ILimage struct is:

typedef struct ILimage
{
	GLuint	Width, Height;	// the image's width and height
	GLuint	Depth;		// the image's depth
	GLubyte	Bpp;		// bytes per pixel (not bits) of the image
	GLuint	Bps;		// bytes per scanline (components for GL)
	GLubyte	*Data;		// the image data
	GLuint	SizeOfData;	// the total size of the data (in bytes)
	GLenum	Format;		// image format (in GL enum style)
	GLenum	Type;		// image data type (in GL enum style)
	GLubyte	*Pal;		// the image palette (if any)
	GLuint	PalSize;	// size of the palette (in bytes)
	GLenum	PalType;	// the palette types
	GLenum	Origin;		// origin of the image
} ILimage;

Almost everything OpenIL does is based on this image struct.  Any file-loading function returns an ILimage struct pointer, so it is the responsibility of the caller to free the memory returned by themselves or by using the ilCloseImage() method described later.


Members of the ILimage struct:

GLuint Width, Height - Simply the width and height of the image.

GLuint Depth - The depth of the image.  Right now, only 1 is accepted.  Hopefully, we will be able to change the library to use 3d images in the future, along with the 1d and 2d images it supports now.

GLubyte Bpp - Bytes per pixel, not bits per pixel, which is what bpp usually stands for.  It is easier on us if we don't have to constantly do Bpp >> 3 to change to bytes in the library.

GLuint Bps - Bytes per scanline, so calculations can be done quicker, especially accessing the actual data of the image without the extra multiply.  This can be found by multiplying Bpp * Width.

GLubyte *Data - This is the actual image data. so everything is done with this.

GLuint SizeOfData - The size of Data, found by multiplying Bps * Height.

GLenum Format - The format of the image, listed in OpenGL's gl/gl.h.  Accepted values are in the range 0x1900 - 0x190A, 0x8000, and 0x80E0 - 0x80E1.  Some values are not used as of yet (note to self:  add in values that aren't =)

GLenum Type - The data type of the image, listed in OpenGL's gl/gl.h.  Accepted values are in the range 0x1400 - 0x140A.

GLubyte *Pal - The image's palette, if one exists.

GLuint PalSize - The size of the palette, in bytes.

GLenum PalType - Type of palette, listed in il/il.h.  Accepted values are in the range 0x0400 - 0x0408.

GLenum Origin - Tells where the image's origin is.  Some images have origins in the upper-left, while others have origins in the lower-left.  Any other origin is not supported at this time.  When saving to a format with a different origin, the library will automatically flip the image if the origin flip is enabled via ilEnable().


The IL_NO_XXX #define's:
------------------------

A user can recompile this library without complete image support in it.  For example, if your project does not use .jpg files, you can put #define IL_NO_JPG at the top of il/il.h, recompile the library, and no .jpg support will be added, meaning quicker compiles and a smaller library.


Required libraries:
-------------------

All libraries needed to compile OpenIL should be included in this package.  If not, please go to openil.sourceforge.net and click on the Required Libraries link.  A list of precompiled libraries with headers and links to the websites for these libraries (if websites for them exist) can be found on this page.


Errors:
-------

All errors generated inside OpenIL, along with illegal parameters passed to OpenIL functions are caught and passed to ilSetError(), an internal library function.  The calling program can call ilGetError() to get the value of the error generated.


Installation:
-------------

Just unzip and compile other libs included if needed...  Edit "copy debug.bat" and "copy release.bat" to copy required files to the places they need to be, e.g. copy il.h to /include/il/il.h.  There should be a cleaner way of doing this, such as the post-build step of Msdev.  I bet there's a nicer way to accomplish this in non-Windows systems.


Usage of this library:
----------------------

To use OpenIL, just call ilInit().  ilClose() is automatically put on the atexit() stack.  This may be changed in the future to where the user need not even call ilInit().  Possibly could be accomplished by DllMain() in Windows...dunno how to do it in Linux though.



=======-----------
Various Functions |
=======-----------


Note on function naming:  If a function name is prefixed with "il", e.g. ilAddAlpha(), then that function can be called outside the dll.  If a function name is only prefixed with an "i", e.g. iCheckExtension(), then that function is specific only to the library and cannot be used by a process outside of the dll.



ILAPI GLboolean ILAPIENTRY ilAddAlpha(ILimage *Image);
-----------
Adds an alpha channel to an image.  Returns true if the operation succeeded, false if the operation failed.  Call ilGetError() on false to find the error.


ILAPI GLvoid ILAPIENTRY ilCloseImage(ILimage *Image);
-----------
Closes Image, freeing all memory in the Data and Pal members and also freeing Image itself.  


ILAPI GLboolean ILAPIENTRY ilCopyImage(ILimage *Dest, ILimage *Src);
-----------
Copies an image from Src to Dest.  Dest must be a valid pointer.  The caller can call ilNewImage(0,0,0,0) and then call this function with the resulting pointer for easiest usage.


ILAPI GLboolean ILAPIENTRY ilCopyImageAttr(ILimage *Dest, ILimage *Src);
-----------
Copies Src's attributes to Dest.  This includes everything but the Data member.  If a palette is present, then it is copied also.


ILAPI ILimage* ILAPIENTRY ilConvertImage(GLenum DestFormat, GLenum DestType, ILimage *Image);
-----------
This function is *supposed* to convert one image format to another.  This function is complete crap as of right now and will be rewritten from scratch.  If DestType is different than GL_UNSIGNED_BYTE or GL_BYTE, then the image is automatically converted to the corresponding GL_UNSIGNED_BYTE or GL_BYTE at the beginning of this function, or at least this is the plan as of now.


ILAPI GLboolean ILAPIENTRY ilConvertPal(GLenum DestType, ILimage *Image);
-----------
Converts a palette'd Image to use the DestType for its PalType.  Right now, only 8-bit images can be passed to this function.   I do not see color quantization in the works, unless someone is willing to do it.  Soon if IL_NO_PAL is DestType, the Image will be converted to a higher byte format with no palette, but as of now (4-9-2000), IL_NO_PAL causes it to error (I think...).  Should this function return a new image instead?


ILAPI GLvoid ILAPIENTRY ilDefaultStates(GLvoid);
-----------
Sets all states to the default status.  There is no way this function can fail (or at least in any way I can see).  If this crashes, then there is something *seriously* wrong with OpenIL.


ILAPI GLboolean	ILAPIENTRY ilDisable(GLenum Mode);
-----------
Disables any OpenIL state.  They can be enabled with ilEnable().  A list of valid states and a short definition follows:

States disabled by default:
---------------------------
IL_ORIGIN_SET - If enabled, 

IL_FILE_OVERWRITE - If enabled, will overwrite an existing file in the saving functions, else they will generate an error if the file exists.

States enabled by default:
--------------------------
None yet


ILAPI GLboolean ILAPIENTRY ilEnable(GLenum Mode);
-----------
See ilDisable().


ILAPI GLboolean ILAPIENTRY ilFlipImage(ILimage *Image);
-----------
Flips a valid image over the x-axis.  (Much like ilMirrorImage()).


ILAPI GLvoid ILAPIENTRY ilGetBooleanv(GLenum Mode, GLboolean *Param);
-----------
Sets the value of Param equal to the state of the Mode specified.  This only works on modes that use boolean values.  Can toggle using ilEnable()/ilDisable().


ILAPI GLenum ILAPIENTRY ilGetError(GLvoid);
-----------
Simply returns IL_NO_ERROR if no error has occurred since the error stack was cleared.  To clear the error stack, call this function until IL_NO_ERROR is returned.  If IL_OUT_OF_MEMORY is returned, exit as quickly and gracefully as possible!  The state of the entire machine is undefined.


ILAPI GLvoid ILAPIENTRY ilGetIntegerv(GLenum Mode, GLint *Param);
-----------
Sets the value of Param equal to the state of the Mode specified.  This only works on modes that use integral values.


ILAPI const GLvoid* ILAPIENTRY ilGetState(GLenum Mode);
-----------
Just like ilGetBooleanv() and ilGetIntegerv(), but it returns the pointer to the current state as a GLvoid pointer, so you must typecast the return.  This saves you having to define a temporary variable, because you can just use the value returned.  The returned pointer cannot be changed, hence the const modifier.  An example used in all the saving routines is:

	if (*((GLboolean*)ilGetState(IL_FILE_MODE)) == false) {
		if (ilFileExists(FileName)) {
			ilSetError(IL_FILE_ALREADY_EXISTS);
			return false;
		}
	}


const char* ILAPIENTRY ilGetString(GLenum StringName);
-----------
Returns a const string describing the OpenIL implementation.  Accepted values are:

GL_VENDOR - Returns the vendor information in a string.
GL_VERSION - Returns the version number in a string.
GL_EXTENSIONS - Returns a string of extension names, which can be searched with ilIsExtensionSupported() to find a specific extension name.  wilGetProcAddress() may be used in the future?  We may use a more elegant method to support extensions.  There are no extensions at the time of this writing (4-9-2000).


ILAPI GLboolean ILAPIENTRY ilInit();
-----------
Look at the "Usage of this library" section for information on this function.


ILAPI GLboolean ILAPIENTRY ilIsDisabled(GLenum Mode);
-----------
Returns a boolean value describing if a Mode is disabled.  Unlike OpenGL, calling this function incurs no heavy performance penalties, since OpenIL is all software.  Just disabling the state using ilDisable() is just as quick as calling this function and deciding whether to disable a Mode or not.


ILAPI GLboolean ILAPIENTRY ilIsEnabled(GLenum Mode);
-----------
Basically the converse of ilIsDisabled().


ILAPI ILimage* ILAPIENTRY ilLoadImage(char *FileName);
-----------
Loads an image based on FileName's extension.  If no extension is given or an invalid extension is provided, this function calls several different checker functions to see what file format FileName is (not yet implemented).  If all else fails, this function returns NULL.


ILAPI GLboolean ILAPIENTRY ilMirrorImage(ILimage *Image);
-----------
Mirrors a valid image over the y-axis.  (Much like ilFlipImage()).


ILAPI ILimage* ILAPIENTRY ilNewImage(GLuint Width, GLuint Height, GLuint Depth, GLubyte Bpp);
-----------
Creates a new ILimage, based on the dimensions given.  For a description of the parameters, look at the description of the ILimage struct above, as the parameters are used in the returned ILimage pointer.  To create an empty image, pass 0 as all the parameters.  A palette is never made in this function.


ILAPI GLboolean ILAPIENTRY ilOriginFunc(GLenum Mode);
-----------
If IL_ORIGIN_MODE is enabled with ilEnable(), then the value this function is passed becomes the new origin, and any image not having this origin is flipped via ilFlipImage().  The default for this is IL_ORIGIN_LOWER_LEFT.  Accepted values are IL_ORIGIN_LOWER_LEFT and IL_ORIGIN_UPPER_LEFT.


ILAPI GLvoid ILAPIENTRY ilPopAttrib(GLvoid);
-----------
Look at ilPushAttrib() for an explanation.


ILAPI GLvoid ILAPIENTRY ilPushAttrib(GLuint Bits);
-----------
OpenIL maintains an attribute stack similar to OpenGL's.  All modes can be preserved by calling this function with IL_ALL_ATTRIB_BITS as the Bits parameter.  This is very useful for when you are loading an image differently than all other images being used and want to maintain the previous state but need to change several states temporarily.  ilPopAttrib() reverts to the previous state.  Every ilPushAttrib() call MUST have a corresponding ilPopAttrib() call, or else you may overflow the attribute stack.  Any OpenIL implementation must have a minimum of  levels on the attribute stack.  If only part of the stack needs to be maintained, call this function with any of the other attribute bits, or'ed together.  Example:

ilPushAttrib(IL_ORIGIN_BIT | IL_FILE_BIT);

This will save only the origin and file states.  This is for when part of the stack needs to be saved but other parts do not.  Valid bits are listed in il/il.h under the "Attribute Bits" section.


ILAPI GLboolean ILAPIENTRY ilRemoveAlpha(ILimage *Image);
-----------
The converse of ilAddAlpha().  If the image is not 32-bit, the image is not changed, because it presumably has no alpha channel.


ILAPI GLboolean ILAPIENTRY ilSaveImage(char *FileName);
-----------
Just like ilLoadImage(), except that it saves based on the extension, and if it cannot find an extension, it fails.


ILAPI ILimage* ILAPIENTRY ilTexSubImage1d(ILimage *Image, GLuint XOff, GLuint Width);
-----------
Similar to OpenGL's glTexSubImage1d().  This function makes a copy of a line of pixels in Image and returns them in a complete ILimage pointer.  If XOff + Width is greater than the image's width, this function returns NULL;


ILAPI ILimage* ILAPIENTRY ilTexSubImage2d(ILimage *Image, GLuint XOff, GLuint YOff, GLuint Width, GLuint Height);
-----------
Similar to OpenGL's glTexSubImage2d().  This function makes a copy of a rectangular portion of pixels in Image and returns them in a complete ILimage pointer.  If XOff + Width is greater than the image's width or YOff + Height is greater than the image's height, this function returns NULL.


ILAPI GLboolean ILAPIENTRY ilSwapColours(ILimage *Image);
ILAPI GLboolean ILAPIENTRY ilSwapColors(ILimage *Image);
-----------
Swaps the colours in an image.  This is useful for when Image is in BGR format but is being saved as a .jpg, which expects RGB format.  This function should be extended to use ABGR format also, if there's a file that uses such a format.


Note for these loading/saving functions!  Potentially dangerous is the fact that they can be JUST an extension (e.g. ".bmp").

=======-----------
Loading Functions |
=======-----------

All loading functions load a file into an ILimage pointer.

ILAPI ILimage* ILAPIENTRY ilLoadBitmap(char *FileName) - .bmp
ILAPI ILimage* ILAPIENTRY ilLoadGif(char *FileName)    - .gif
ILAPI ILimage* ILAPIENTRY ilLoadJpeg(char *FileName)   - .jpg
ILAPI ILimage* ILAPIENTRY ilLoadPcx(char *FileName)    - .pcx
ILAPI ILimage* ILAPIENTRY ilLoadPgm(char *FileName)    - .pgm
ILAPI ILimage* ILAPIENTRY ilLoadPgmPpm(char *FileName) - .pgm or .ppm
ILAPI ILimage* ILAPIENTRY ilLoadPpm(char *FileName)    - .ppm
ILAPI ILimage* ILAPIENTRY ilLoadPng(char *FileName)    - .png
ILAPI ILimage* ILAPIENTRY ilLoadTarga(char *FileName)  - .tga



=======----------
Saving Functions |
=======----------

All saving functions save an ILimage pointer as a file.

ILAPI GLboolean ILAPIENTRY ilSaveBitmap(char *FileName);
-----------
Just saves as a .bmp file.


ILAPI GLboolean ILAPIENTRY ilSaveCHeader(char *FileName, ILimage *Image, char *InternalName);
-----------
Saves Image as a C-style header file (.h).  InternalName is the name of the array created in the .h file.


ILAPI GLboolean	ILAPIENTRY ilSaveJpeg(char *FileName, ILimage *Image, GLuint Quality);
-----------
Saves Image as a .jpg file.  Quality is an integer from 1-99 specifying the quality of the image to be output, since Jpeg uses a lossy compression scheme.  1 is poor quality, while 99 is excellent quality.  1 results in a smaller file, while 99 results in a larger file.


ILAPI GLboolean	ILAPIENTRY ilSavePcx(char *FileName, ILimage *Image);
-----------
Saves Image as a .pcx.  (Not implemented yet).


ILAPI GLboolean	ILAPIENTRY ilSaveTarga(char *FileName, ILimage *Image, ILTargaSave *AuthSpec);
-----------
Saves Image as a .tga.  AuthSpec can be either NULL or an ILTargaSave struct.  ILTargaSave is defined in il/il.h as:

typedef struct ILTargaSave
{
	GLbyte	*ID;		// whatever the user wants for the id, or else we use our generated one
	GLubyte	 IDLen;		// length of the ID string
	GLbyte	 AuthName[41];	// the author's name
	GLbyte	 AuthComm[324];	// the author's comments
	GLint	 KeyColor;	// not used as of now
} ILTargaSave;

ID is any identification the author wants for the targa.  "My Big Brown Shoe" is an example.  IDLen must be 255 or less.  IDLen can be 0 if no ID is desired.  AuthName houses the author's name.  AuthComm houses any comments the author (or anyone else for that matter...) wants to make about this image.  KeyColor is not used as of yet, but, in the future, if not 0, it will be split-up into its rgb components, and transparency can be based on this.  Useful for images that need transparency but need to be 24-bit or take too much space with an alpha channel.



Additional Reading
------------------

All image formats used in OpenIL have corresponding documents on http://www.wotsit.org, under the Graphics Files section.  These documents proved invaluable for the creation of this library when there was no library already available for that image format.


Legalese
--------

Open Image Library (OpenIL) is in no way associated with the Open Graphics Library (OpenGL) provided by Silicon Graphics Incorporated and several other vendors.  OpenGL is a trademark of Silicon Graphics Incorporated.

All contents of this file are intellectual property of Denton Woods, copyright 2000.