/* This example use of imageio.library loads the image file specified
		on the command line at half size by converting it to a memory based
		buffer (for demonstrating the use of memory buffers).
*/

#include <stdio.h>

#include <dos/dos.h>
#include <exec/memory.h>
#include <exec/types.h>

#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/cybergraphics_protos.h>
#include <clib/intuition_protos.h>

#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/cybergraphics_pragmas.h>

#include <cybergraphics/cybergraphics.h>

#include <imageio/imageio.h>
#include <imageio/imageio_protos.h>
#include <imageio/imageio_pragmas.h>

#include <guigfx/guigfx.h>
#include <pragmas/guigfx_pragmas.h>
#include <guigfx/guigfx_protos.h>

/* Function prototypes */
__saveds __asm ULONG progressFunc( register __d0 ULONG curr, register __d1 ULONG lines, register __a0 void *userdata );

extern struct Library *DOSBase;
struct Library *ImageIOBase, *IntuitionBase;

void main( int argc, char **argv )
{
	if ( argv[1] != NULL )
	{
		ImageIOBase = OpenLibrary( "imageio.library", 2 );
		IntuitionBase = OpenLibrary( "intuition.library", NULL );
		if ( IntuitionBase && ImageIOBase )
		{
			struct FileInfoBlock *fib;

			fib = AllocDosObject( DOS_FIB, NULL );
			if ( fib )
			{
				BPTR lock;

				lock = Lock( argv[1], ACCESS_READ );
				if ( lock )
				{
					if ( Examine( lock, fib ) )
					{
						UBYTE *rgbbuffer;

						rgbbuffer = AllocVec( fib->fib_Size, MEMF_PUBLIC | MEMF_CLEAR );
						if ( rgbbuffer )
						{
							BPTR fp;

							fp = Open( argv[1], MODE_OLDFILE );
							if ( fp != NULL )
							{
								if ( Read( fp, rgbbuffer, fib->fib_Size ) == fib->fib_Size )
								{
									struct ImageHandle *ih;
									ULONG err;

									err = AllocImage( &ih,
										IMG_SrcMemStream, rgbbuffer,
										IMG_SrcMemStreamSize, fib->fib_Size,
										TAG_DONE );
									if ( !err )
									{
										ULONG num = 1, denom = 2;
										ULONG x, y, bpp, rs;
										UBYTE *buffer, cs, it;

										err = GetImageAttrs( ih,
											IMG_Width, &x,
											IMG_Height, &y,
											IMG_BytesPerPixel, &bpp,
											IMG_ColourSpace, &cs,
											IMG_RowSize, &rs,
											IMG_ImageType, &it,
											IMG_TestScaleNum, num,
											IMG_TestScaleDenom, denom,
											TAG_DONE );
										if ( !err )
										{
											printf( "width=%ld, height=%ld\n", x, y );
											printf( "bytes per pixel=%ld, colourspace=%d\n", bpp, cs );
											printf( "row size=%ld\n", rs );
											printf( "image type=%d\n", it );

											err = ReadImage( ih,
												IMG_ScaleNum, num,
												IMG_ScaleDenom, denom,
												IMG_ImageBuffer, &buffer,
												IMG_ProgressHook, progressFunc,
												TAG_DONE );
											if ( !err )
											{
											}
											else printf( "read image error:%d\n", err );
										}
										else printf( "get image attrs error:%d\n", err );

										FreeImage( ih );
									}
									else printf( "alloc image error:%d\n", err );
								}
								else printf( "read error on file\n" );

								Close( fp );
							}
							else printf( "cant open file\n" );

							FreeVec( rgbbuffer );
						}
						else printf( "cant allocate %ld bytes of memory\n", fib->fib_Size );
					}
					else printf( "cant examine %s\n", argv[1] );

					UnLock( lock );
				}

				FreeDosObject( DOS_FIB, fib );
			}
		}

		if ( ImageIOBase ) CloseLibrary( ImageIOBase );
		if ( IntuitionBase ) CloseLibrary ( IntuitionBase );
	}
	else printf( "no file specified\n" );
}

__saveds __asm ULONG progressFunc( register __d0 ULONG curr, register __d1 ULONG lines, register __a0 void *userdata )
{
	static int prevpercent = 0;

	int percent = ( curr * 100 ) / lines;

	if ( prevpercent != percent )
	{
		if ( percent % 10 == 0 ) printf( "%d%%\n", percent );
	}

	prevpercent = percent;

	return NULL;
}
