#include "ninox.h"

struct HotPixel {
   int x,y;
   int count;
   };

static int Frames = 0;
static struct HotPixel *List;
static int nHotPixels = 0;

static int AddToList(int x,int y);

// define hot pixels to be pixels that are more than 50 percent brighter than
// all their 8 neighbors on all frames (ie they don't move)
int
do_DetectHotPixels(struct Image *img)
	{
	int x,y;
	int width = img->width;
	int height = img->height;
	int depth = img->depth;
	unsigned char *data = (unsigned char *)img->data;
	unsigned short *udata = (unsigned short *)img->data;
	int threshhold = 200;

	++Frames;

	switch(depth) {
	   case 8:
		for(y=1; y<height-1; ++y) {
		   int o = y * width + 1;
		   for(x=1; x<width-1; ++x,++o) {
			int p = data[o];
			if (p > threshhold && (
				data[o-width-1]< threshhold &&
				data[o-width]<   threshhold &&
				data[o-width+1]< threshhold &&
				data[o-1]<   threshhold &&
				data[o+1]<   threshhold &&
				data[o+width-1]< threshhold &&
				data[o+width]<   threshhold &&
				data[o+width+1]< threshhold))
			   AddToList(x,y);
			}
		   }
		break;
	   case 16:
		threshhold <<= 8;

		for(y=1; y<height-1; ++y) {
		   int o = y * width + 1;
		   for(x=1; x<width-1; ++x,++o) {
			int p = udata[o];
			if (p > threshhold && (
				udata[o-width-1]< threshhold &&
				udata[o-width]<   threshhold &&
				udata[o-width+1]< threshhold &&
				udata[o-1]<   threshhold &&
				udata[o+1]<   threshhold &&
				udata[o+width-1]< threshhold &&
				udata[o+width]<   threshhold &&
				udata[o+width+1]< threshhold))
			   AddToList(x,y);
			}
		   }
	   	break;
	      default:
		printf("DetectHotPixels: Depth %d not supported\n",depth);
		break;
	   	}

	return 1;
	}
	
static int
AddToList(int x,int y)
	{
	int n;

	if (! nHotPixels) {
	   nHotPixels = 32;
	   List = (struct HotPixel *) ZeroMalloc(nHotPixels * sizeof(struct HotPixel));
	   }

	for(n=0; n<nHotPixels; ++n)
	   if (List[n].x == x && List[n].y == y) {
		++List[n].count;
		return 1;
		}
	   else if (List[n].x == 0 && List[n].y == 0) {
		List[n].x = x;
		List[n].y = y;
		List[n].count = 1;
		return 1;
		}

	nHotPixels += 32;
	List = (struct HotPixel *)realloc(List,nHotPixels * sizeof(struct HotPixel));

	// new entry
	List[n].x = x;
	List[n].y = y;
	List[n].count = 1;

	return 1;
	}
	   
int
WriteHotPixelFile(char *fname)
	{
	int i;

	FILE *z = OpenLogfile(fname,"w");

	if (z == NULL) {
	   printf("Error creating log file '%s'\n",fname);
	   return 0;
	   }

	for (i=0; i<nHotPixels && List[i].x>0 && List[i].y>0; ++i) {
	   if (List[i].count == Frames) fprintf(z,"%d %d\n",List[i].x,List[i].y);
	   }

	fclose(z);
	return 0;
	}
