Writing custom data streams


The class iDataStream provides an abstract interface for data streams that can be used to read and write images.
All of the image classes have functions to load images from files (iFileStream) and memory (iMemoryStream); but they also have functions that accept the address of any stream inherited from iDataStream.
So, by writing a data stream class inherited from iDataStream, imagen can use your class when reading and writing images.

For examples on how a stream class can be written, check out the source code for iFileStream and iMemoryStream.

iDataStream is an abstract class. When inheriting from it, the following functions must be implemented:

You will, of course, want to implement an open() function to open your stream, even though it is not a part of the virtual interface.


bool close()

Closes the stream.
Should return true if the stream was closed successfully, else false.

long read( void *data, long size, long count )

Reads data from the stream.

data : The array to place the read data into.
size : The size in bytes of each element to read.
count : The number of elements to read.

Should return the number of elements read.

long write( const void *data, long size, long count )

Writes data to the stream.

data : The array of data to write.
size : The size in bytes of each element to write.
count : The number of elements to write.

Should return the number of elements written.

int getc()

Reads a character from the stream.

If successful, should return the character read as an integer value, else 0.

int putc( int chr )

Writes a character to the stream.

If successful, should return the character that was written, else 0.

bool flush()

Flushes the stream.
Should return true if successful, else false.

long size()

Should return the size of the stream.

long tell()

Should return the current value of the stream's position indicator

bool seek( long offset, iDataSeek origin )

Sets the position of the stream's position indicator.

offset : The new position relative to origin.
origin : The reference position to add offset to.

Should return true if successful, else false.

bool atEnd()

Should return true if the end of the stream has been reached, else false.


To read an image with your newly created stream class, simply pass its address to the image's load function.
#include <imagen/iImage.h>

using namespace imagen;

iImage image;
MyStream stream;

stream.open();
image.load(&stream);
stream.close();

Use the same process for writing images, too.
#include <imagen/iImage.h>

using namespace imagen;

iImage image;
MyStream stream;

stream.open();
image.save(&stream);
stream.close();

imagen will now call your stream functions when reading/writing images. It's that simple!