/*
 * Datatype recognition hook function for MacPaint pictures.
 * Based on org_desc_macpaint.c by Erik Engdahl <mx3erik@mtek.chalmers.se> which based
 * on the descriptor for macpaint.datatype from NDUK 3.1.
 *
 * Written from TetiSoft@apg.lahn.de (Detlef Wuerkner)
 * Even Erik's better desc_macpaint.c recognized Compugraphic fonts as MacPaint
 * pictures, so I decided to write a function that checks deeper: It tests
 * if the data is packed with the PackBits procedure.
 *
 * In worst case, ~50k are tested. Therefore buffered I/O is used to speed it up.
 */

#include <exec/memory.h>
#include <dos/dosextens.h>
#include <datatypes/datatypes.h>

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

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

#define SysBase	dthc->dthc_SysBase
#define DOSBase	dthc->dthc_DOSBase

BOOL __asm __interrupt DTHook (register __a0 struct DTHookContext * dthc)
{
	BOOL result = FALSE;
	ULONG i;
	UBYTE *buf = NULL;
	BPTR fh;

	if(						/* Make sure we have */
	   (fh = dthc->dthc_FileHandle) &&		/* a filehandle, */
	   (buf = AllocVec(1024, MEMF_PUBLIC)) &&	/* a buffer, */
	   (Seek(fh, 0, OFFSET_BEGINNING) != -1) &&	/* avoided bug in datatypes.lib 40.6 */
	   (FRead(fh, buf, 512, 1) == 1)		/* and can read the first 512 bytes */
	  )
	{
		if(					/* Check for resource fork: */
		   (buf[0] == 0) &&			/* First byte is zero */
		   (buf[1] >= 0 && buf[1] < 0x40) &&	/* Check for comment */
		   (*(ULONG*)&buf[0x41]==0x504E5447) && /* Check for PNTG mark */
		   (buf[0x4b] == 0)			/* Zero check */
		  )
			result = TRUE;
		else if(*(ULONG *)buf <= 4)		/* Check header in data fork: Version number */
		{
			/* 204 reserved bytes must be zero */
			for(result=TRUE, i = 308; (i < 512) && (result==TRUE); i++)
				if(buf[i] != 0) result = FALSE;

			/* Check for correct bitpacked 720*576 pixels */
			if(result == TRUE)
				for(i = 0; (i < 720) && (result == TRUE); i++)
				{
					UBYTE c;
					LONG col = 0;
					while (col < 72)
					{
						if(FRead(fh, &c, 1, 1) != 1)
						{
							result = FALSE;
							break;
						}
						if(c < 128)
						{
							col += ++c;
							if(FRead(fh, buf, c, 1) != 1)
							{
								result = FALSE;
								break;
							}
						}
						else
						{
							col += (256 - c + 1);
							if(FRead(fh, buf, 1, 1) != 1)
							{
								result = FALSE;
								break;
							}
						}
					}
					if (col != 72) result = FALSE;
				}
		}
	}
	if(fh) Flush(fh);
	if(buf) FreeVec(buf);
	return result;
}
