/*	This example use of jpeg.library loads the jpeg file specified
		on the command line and saves a version halved in size to
		'RAM:halved.jpg'. It uses de/compress hooks to store/supply the image
		data to/from jpeg.library. This example uses memory based jpeg
		streams for the source/destination images.

		Does NOT support greyscale jpegs (not implemented in this application
		but jpeg.library supports them).
*/

#include <stdio.h>

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

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

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

#include "jpeg/jpeg.h"
#include "jpeg/jpeg_protos.h"
#include "jpeg/jpeg_pragmas.h"

/* Function prototypes */
__saveds __asm storeline( register __a0 void *scanline, register __d0 ULONG line, register __d1 ULONG bytes, register __a1 void *userdata );
__saveds __asm getline( register __a0 UBYTE **scanline, register __d0 ULONG line, register __d1 ULONG width, register __a1 void *userdata );

extern struct Library *DOSBase;
struct Library *JpegBase;

char *version = "$VER: savemem 1.1 (11.2.2000)";

void main( int argc, char **argv )
{
	if ( argv[1] )
	{
		JpegBase = OpenLibrary( "jpeg.library", NULL );
		if ( JpegBase != NULL )
		{
			ULONG err;
			struct JPEGDecHandle *jph;
			struct JPEGComHandle *jpc;
			UBYTE *buffer;
			ULONG x, y;
			BPTR fp, out;
			UBYTE colourspace;

			fp = Open( argv[1], MODE_OLDFILE );
			out = Open( "ram:halved.jpg", MODE_NEWFILE );
			if ( fp != NULL && out != NULL )
			{
				err = AllocJPEGDecompress( &jph, JPG_SrcFile, fp, TAG_DONE );
				if ( !err )
				{
					err = GetJPEGInfo( jph,
						JPG_Width, &x, JPG_Height, &y,
						JPG_ColourSpace, &colourspace,
						JPG_ScaleNum, 1, JPG_ScaleDenom, 2,
						TAG_DONE );
					if ( !err )
					{
						printf( "colourspace=%d\n", colourspace );
						printf( "scaled by half to %d x %d\n", x, y );

						buffer = AllocBufferFromJPEG( jph,
							JPG_ScaleNum, 1, JPG_ScaleDenom, 2,
							TAG_DONE );
						if ( buffer != NULL )
						{
							err = DecompressJPEG( jph, JPG_DecompressHook, storeline,
								JPG_DecompressUserData, buffer,
								JPG_ScaleNum, 1, JPG_ScaleDenom, 2,
								TAG_DONE );
							if ( !err )
							{
								err = AllocJPEGCompress( &jpc, JPG_DestFile, out, TAG_DONE );
								if ( !err )
								{
									err = CompressJPEG( jpc,
										JPG_CompressHook, getline,
										JPG_CompressUserData, buffer,
										JPG_Width, x, JPG_Height, y,
										TAG_DONE );
									if ( !err )
									{
										printf( "jpeg saved ok\n" );
									}
									else printf( "compress jpeg error:%d\n", err );

									FreeJPEGCompress( jpc );
								}
								else printf( "alloc jpeg error:%d\n", err );
							}
							else printf( "decompress jpeg error:%d\n", err );

							FreeJPEGBuffer( buffer );
						}
						else printf( "cant allocate rgb buffer\n" );
					}
					else printf( "get jpeg info error:%d\n", err );

					FreeJPEGDecompress( jph );
				}
				else printf( "alloc jpeg error:%d\n", err );
			}
			else printf( "cant open source or target file\n" );

			if ( fp != NULL ) Close( fp );
			if ( out != NULL ) Close( out );
		}

		if ( JpegBase != NULL ) CloseLibrary( JpegBase );
	}
	else
	{
		printf( "no source file specified\n" );
	}
}

__saveds __asm storeline( register __a0 void *scanline, register __d0 ULONG line, register __d1 ULONG bytes, register __a1 void *userdata )
{
	UBYTE *buffer = userdata;

	CopyMem( scanline, buffer + ( ( line - 1 ) * bytes ), bytes );

	return NULL;
}

__saveds __asm getline( register __a0 UBYTE **scanline, register __d0 ULONG line, register __d1 ULONG width, register __a1 void *userdata )
{
	UBYTE *buffer = userdata;

	*scanline = &buffer[ width * 3 * line ];

	return NULL;
}
