/*	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 displays all comment markers in the original file
		using jpeg.library routines and copies any markers present in the
		original jpeg stream to the new jpeg file.

		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: copymarkers 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;
			struct MinList *markerlist;

			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,
									JPG_ReadMarker, M_ALL,
									TAG_DONE );
								if ( !err )
								{
									err = GetJPEGInfo( jph,
										JPG_Width, &x, JPG_Height, &y,
										JPG_ColourSpace, &colourspace,
										JPG_ScaleNum, 1,
										JPG_ScaleDenom, 2,
										JPG_MarkerList, &markerlist,
										TAG_DONE );
									if ( !err )
									{
										struct JPEGMarker *curr;

										printf( "scaled by half to %d x %d\n", x, y );

										curr = GetJPEGMarker( jph,
											JPG_MarkerFirst, M_COM,
											JPG_MarkerExists, TRUE,
											TAG_DONE );

										while ( curr )
										{
											printf( "marker=%x\n", curr->mk_ID );
											printf( " length=%ld\n", curr->mk_Length );

											if ( curr->mk_ID == M_COM )
											{
												printf( " data=%s\n", (char *)curr->mk_Data );
											}

											curr = GetJPEGMarker( jph,
												JPG_MarkerNext, curr,
												JPG_MarkerExists, TRUE,
												JPG_MarkerType, M_COM,
												TAG_DONE );
										}

										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,
													JPG_MarkerList, markerlist,
													TAG_DONE );
												if ( !err )
												{
													err = CompressJPEG( jpc,
														JPG_SrcRGBBuffer, buffer,
														JPG_Width, x,
														JPG_Height, y,
														JPG_Progressive, FALSE,
														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;
}
