/**********************************************************/
/* Copyright   ©1999 Wolf-Juergen Faust                   */
/* Am Dorfgarten 10                                       */
/* 60435 Frankfurt     EXAMPLE.c                          */
/* Germany                                                */
/* Tel: +(49) 69 5486556                                  */
/* Fax: +(49) 69 95409598                                 */
/* email: wfaust@stud.uni-frankfurt.de                    */
/*                                                        */
/* This piece of source code was based on ICSConvert      */
/* and shows how to call ICS for color correction.        */
/* See the included comments and ICS.doc for more         */
/* info when adding ICS support to your software          */
/*                                                        */
/* The source opens a source image file and saves         */
/* the corrected values in a new destination file         */
/*                                                        */
/**********************************************************/

#include	<proto/ics.h>

struct Library *ICSBase=NULL;


/*** MAIN ***/
{
	UWORD ret = 1;

	UWORD wi,wn,wx;
	ULONG x,y, h, size, li;
	struct IFFHandle *iffhandle;
	UBYTE *temp;
	void *idc;
	void *idctrans;
	uint_fast32_t oldmode;
	COLOR incolor, outcolor;
	UBYTE *r,*g,*b;

	if (ICSBase = OpenLibrary("ics.library",2L))  // Note first public release will be V2!
	{										
		if(idc = CreateIDC(                // create ICS device context object
			ICS_APPNAME, PRGMNAME,           // name of this application
			ICS_APPNAMEVERSION, NUMVERSION,  // version of this application
			ICS_APPICSVERSION, 2,            // version of ICS library this application was made for/with.  Note V2 will be the first public release.
			TAG_DONE))
		{
			if(SetupIDCColorMatching(idc, dscreen, TAG_DONE)>1)  // display ICS preference window. ICSConvert does abort if the user selects cancel (returns 1)
			{
				if(oldmode = SetIDCMode(idc, ICS_ON)) // make sure ICS is enabled during CreateIDCTransform even if the current preference setting is off... in order to may enable it later. See docs about SetIDCMode().
				{
					if(idctrans = CreateIDCTransform(idc,
						ICS_TransferDevices, ICS_INPUT_DEVICE,        // We want to convert from input to display device (not printer device)
						ICS_StatusOpen, dscreen,                      // Screen to use for status window or NULL for default public screen
						ICS_StatusTitle, "ICS Image Conversion",      // Overwrite status window title with our own...
						//ICS_StatusActivate, TRUE,                     // Activate status window
						ICS_StatusKeep, TRUE,                         // keep status window open as we use the ics status window during conversion of image data later
						// ICS_StatusDisableAbort, TRUE,                 // use this to disable Abort/Stop button
						TAG_DONE)) // create input (scanner) to device (display/monitor) color corretion and show status window while processing.. leave status window open for user below...
					{
						if(SetIDCMode(idc, oldmode)) // here we reset the ICS mode to the wanted preferences or application program setting...
						{
							ICSStatusWin(idctrans, ICS_StatusText,  "Opening image file...", TAG_DONE);  // change text of status window created by ICS library during CreateIDCTransform()
							if(ret)
							{
								if(ICSStatusWin(idctrans, ICS_StatusCheck,  0, TAG_DONE)) // check if user pressed abort in the status window
								{
									ret = 0;
								}
							}
							if(ret)
							{
								if (GetMain(ilbm, POPEN, win2, 0))  // open source image file for conversion
								{
									if (GetMain(ilbm, PREADINIT, win2, 0))  // init read routines for file
									{
										if(iffhandle = OPENMYFILE(ilbm, win2)) // open destination image file for color corrected image
										{
											for(ret=1,y=0; (ret) && (y<ilbm->hssize); y++)  // loop for number of lines in image
											{
												// Display progress status and check for user abort...
												sprintf(tempstr,"Converting Image  -  %ld%% complete",(y*100)/ilbm->hssize);
												 // change status text and update progress bar. Also check if user wants to abort... tempstr may be used after StatusWin call as ICS does make a copy of tempstr.
												if(ICSStatusWin(idctrans, ICS_StatusText,  tempstr, ICS_StatusProgress, (y*100)/ilbm->hssize, ICS_StatusCheck,  0, TAG_DONE))
												{
													ret = 0;
													break;
												}
												// read a single image line into buffer.
												if(temp = (UBYTE *)GetMain(ilbm, PREADLINE, win2, y))
												{
													r = temp;
													g = temp + ilbm->wssize;
													b = temp + ilbm->wssize;
													// color correct a single line using ICS. If ICS is disabled, this function TranslateColors() will copy in to output unchanged.
													for(x=0; (ret) && (x<ilbm->wssize); x++)  // loop for number of pixels in line
													{
														if(ilbm->destmode) // is source a grayscale image?
														{
															incolor.ugray.gray = (temp[x]<<8) | temp[x];  // convert 8 bit to 16 bit unsigned graylevel. IMPORTANT: Black=0   White=65535
															if(!(TranslateColors(idctrans, &incolor, 1, COLOR_UGRAY, &outcolor, COLOR_UGRAY)))
															{
																temp = ICSFault(idc, "Error setting ICS mode by "PRGMNAME".");
																if(!temp) temp = "Error: Can't enable or disable ICS.";
																if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
																ret = 0;
																break;
															}
															temp[x] = outcolor.ugray.gray >> 8;
														} else
														{
															incolor.urgb.red   = (r[x]<<8) | r[x];  // convert 8 bit to 16 bit unsigned RGB color
															incolor.urgb.green = (g[x]<<8) | g[x];
															incolor.urgb.blue  = (b[x]<<8) | b[x];
															if(!(TranslateColors(idctrans, &incolor, 1, COLOR_URGB, &outcolor, COLOR_URGB))) // Note: This just corrects a single pixel. It's much faster to correct at least a complete row!
																temp = ICSFault(idc, "Error setting ICS mode by "PRGMNAME".");
																if(!temp) temp = "Error: Can't enable or disable ICS.";
																if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
																ret = 0;
																break;
															}
															r[x] = outcolor.urgb.red >> 8;  // Convert 16 to 8 Bit - Correct would be to devide by 65535/255=257 and not 256... but we ignore the invisible fault introduced...
															g[x] = outcolor.urgb.green >> 8;
															b[x] = outcolor.urgb.blue >> 8;
														}
													}
													if(!(WRITEMYLINE(ilbm, win2, iffhandle, temp)))
													{
														ret = 0;
														break;
													}
												} else
												{
													ret = 0;
													break;
												}
											}
											CLOSEMYFILE(iffhandle);
										}
										GetMain(ilbm, PREADEND, win2, 0);
									} else
									{
										ret = 0;
									}
									GetMain(ilbm, PCLOSE, win2, 0);
								}
							}
						} else
						{
							temp = ICSFault(idc, "Error setting ICS mode by "PRGMNAME".");
							if(!temp) temp = "Error: Can't enable or disable ICS.";
							if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
							ret = 0;
						}
						DeleteIDCTransform(idctrans);
					} else
					{
						temp = ICSFault(idc, "Error while running "PRGMNAME".");
						if(!temp) temp = "Error: Can't create color transformation using ics.library";
						if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
						ret = 0;
					}
				} else
				{
					temp = ICSFault(idc, "Error enabling ICS by "PRGMNAME".");
					if(!temp) temp = "Error: Can't enable ICS.";
					if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
					ret = 0;
				}
			} else
			{
				temp = ICSFault(idc, "Error while running "PRGMNAME".");
				if(!temp) temp = "Error: Can't open ICS preferences.";
				if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, NULL);
				ret = 0;
			}
			DeleteIDC(idc);
		} else
		{
			Mes("Error: Can't create device context using ics.library\n      Maybe not enough memory?", win2);
		}
		CloseLibrary(ICSBase);
	}
	return(ret);
}
