/*
  Copyright (C) 1999 E. H. Haley

  jpeg->YIQ, wav tx, zero some (menu), tx back ->rgb->show loop.

  sig was: find the top M of N=65535ish entries -- what coefficient
  and what value. Run like "sig 100 hand8.jpeg" sets M, you make an
  index matrix, etc., so you can zero them one at a time in order by
  hitting e.g. + or -, etc.

  now sigrun: let it zoom up and down itself.  toggle w/ ' '.  BTW,
  the heap-select isn't so great for M=N!  */

#include <GL/glut.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>
#include "wto.h"
#include <jpeglib.h>
#include "loadj.h"
#include "color.h"
#include "top.h"

int w,h, m, cc=0, upness=1, firsttime=1;
JSAMPLE *arr;
float *coeffs, *tops, *scratch;
unsigned long *inds;
char *filename;

void init(int aardc, char **aardv)
{
  int i;
  
  glClearColor(0.0,0.0,0.0,1.0);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

  if (aardc>1)
    {
      filename=*(aardv+1);
      arr=ljf(filename,&w,&h);
      m=3*w*h;       // m=atoi(*(aardv+2));
            
      coeffs=(float *)calloc(3*w*h,sizeof(float));
      scratch=(float *)calloc(3*w*h,sizeof(float));
      tops=(float *)calloc(m,sizeof(float));
      inds=(unsigned long *)calloc(m,sizeof(unsigned long));

      for(i=0; i<3*w*h; i++)
	scratch[i]=0.0;
      for(i=0; i<w*h; i++)
	rgb256yiq(arr+3*i,coeffs+3*i);

      wtc(coeffs, (unsigned long) w, (unsigned long) h,
	    0,0,w,h,
	    1,daub4);

      top(m,3*w*h,coeffs-1,tops-1,inds-1);
      //      for(i=0; i<m; i++)
      //	printf("%ld\t%0.3f\n",inds[i],tops[i]);
    }
  else
    { printf("Usage: sigrun [filename]\n"); exit(0); } 
}


void idle(void)
{
  int i;

  if(firsttime==1)
    {
      firsttime=0;     //arr is correct--original still
      printf("\nOriginal image\n");
    }
  else
    {
      cc+=upness;

      for(i=0; i<3*w*h; i++)
	scratch[i]=0;
      for(i=0; i<cc; i++)
	scratch[inds[i]]=coeffs[inds[i]];

      //      if (upness>0) scratch[inds[cc-1]]=coeffs[inds[cc-1]];
      //      else scratch[inds[cc]]=0.0;

      wtc(scratch, (unsigned long) w, (unsigned long) h,
	    0,0,w,h,
	    -1,daub4);
      for(i=0; i<w*h; i++)
	yiq256rgb(scratch+3*i,arr+3*i);  

      printf("%d\n",cc);
    }

  glutPostRedisplay();
}

void display(void)
{
  glDrawPixels(w,h, GL_RGB, GL_UNSIGNED_BYTE, arr);
  glutSwapBuffers();
}

void mouse(int button, int state, int x, int y)
{
  if ((button==GLUT_LEFT_BUTTON)&&(state==GLUT_UP))
    {
      free(arr);
      free(coeffs);
      free(inds);
      free(scratch);
      free(tops);
      exit(0);
    }
}

void keyb(unsigned char key, int x, int y)
{
  upness=(upness>0?-1:1);
}

int main(int aardc, char **aardv)
{
  init(aardc, aardv);
  glutInit(&aardc, aardv);

  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA );
  glutInitWindowSize(w,h);
  glutCreateWindow(aardv[0]);
  glutDisplayFunc(display);
  glutMouseFunc(mouse);
  glutIdleFunc(idle);
  glutKeyboardFunc(keyb);

  glutMainLoop();
  exit(0);
}











