/*	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 write a "dots per inch" tg and x and y densities
		of 300 x 300.

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

#include <stdio.h>
#include <string.h>

#include <dos/dos.h>
#include <exec/memory.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 ULONG progressFunc( register __d0 ULONG curr, register __d1 ULONG lines, register __a0 void *userdata );

extern struct Library *DOSBase;
struct Library *JpegBase;

char *version = "$VER: writedensity 1.0 (11.2.2000)";

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

			fib = AllocDosObject( DOS_FIB, TAG_DONE );
			if ( fib != NULL )
			{
				lock = Lock( argv[1], ACCESS_READ );
				if ( lock != NULL )
				{
					if ( Examine( lock, fib ) )
					{
						jstreamsize = fib->fib_Size;

						jstream = AllocVec( jstreamsize, MEMF_PUBLIC | MEMF_CLEAR );
						if ( jstream != NULL )
						{
							fp = OpenFromLock( lock );
							if ( fp != NULL )
							{
								lock = NULL; // Lock is consumed by OpenFromLock()

								/* Spool file into memory */
								Read( fp, jstream, jstreamsize );

								err = AllocJPEGDecompress( &jph,
									JPG_SrcMemStream, jstream,
									JPG_SrcMemStreamSize, jstreamsize,
									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( "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_DestRGBBuffer, buffer,
												JPG_ProgressHook, progressFunc,
												JPG_ScaleNum, 1,
												JPG_ScaleDenom, 2,
												TAG_DONE );
											if ( !err )
											{
												err = AllocJPEGCompress( &jpc,
													JPG_DestMemStream, &cstream,
													JPG_DestMemStreamSize, &cstreamsize,
													TAG_DONE );
												if ( !err )
												{
													err = CompressJPEG( jpc,
														JPG_SrcRGBBuffer, buffer,
														JPG_Width, x,
														JPG_Height, y,
														JPG_Progressive, FALSE,
														JPG_DensityUnits, DENSITYUNITS_DOTSINCH,
														JPG_XDensity, 300,
														JPG_YDensity, 300,
														TAG_DONE );
													if ( !err )
													{
														out = Open( "ram:halved.jpg", MODE_NEWFILE );
														if ( out != NULL )
														{
															Write( out, cstream, cstreamsize );

															printf( "jpeg saved ok\n" );

															Close( out );
														}
													}
													else printf( "compress jpeg error:%d\n", err );

													if ( cstream != NULL ) FreeVec( cstream );

													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 );

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

							FreeVec( jstream );
						}
						else printf( "cant allocate jstream buffer\n" );
					}
					else printf( "cant examine file\n" );

					if ( lock ) UnLock( lock );
				}
				else printf( "cant open file\n" );

				FreeDosObject( DOS_FIB, fib );
			}
			else printf( "cant allocate fib\n" );
		}
		else printf( "you need jpeg.library v6.0 minimum\n" );

		if ( JpegBase != NULL ) CloseLibrary( JpegBase );
	}
	else
	{
		printf( "no source 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;
}
