/******************************************************************************/
/*                                                                            */
/*  BW_MAP - Similar to colormap(), except black and white                    */
/*                                                                            */
/******************************************************************************/

#define STRICT
#include <windows.h>
#include <commctrl.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <new.h>
#include <float.h>

#include "const.h"
#include "classes.h"
#include "extern.h"
#include "funcdefs.h"
#include "julia.rh"

void bw_map ()
{
   int irow, icol, itone ;
   unsigned int *dwell_ptr, min_dwell, max_dwell, dwell_tone;
   unsigned char *raw_ptr, tone, black, white ;
   double mult, log_min ;

/*
   Find the range of dwells.  The minimum will have a brightness equal to
   CmapFloor percent, and the the maximum will have full brightness.
   Thus, 'black' need not be fully black, although white will be fully white.
*/

   min_dwell = MAXPOSNUM ;
   max_dwell = 0 ;

   for (irow=0 ; irow<RowResolution ; irow++) {
      dwell_ptr = dwells + irow * ColResolution ;
      for (icol=0 ; icol<ColResolution ; icol++) {
         if (dwell_ptr[icol] < min_dwell)
            min_dwell = dwell_ptr[icol] ;
         if (dwell_ptr[icol] > max_dwell)
            max_dwell = dwell_ptr[icol] ;
         }
      }

   if (min_dwell < CmapNlinear + 1)
      min_dwell = CmapNlinear + 1 ;

   if (max_dwell <= min_dwell)
      max_dwell = min_dwell + 1 ;

   log_min = log ( (double) min_dwell ) ;
   mult = (CmapNlog - 0.00001) / (log ( (double) max_dwell ) - log_min) ;

   // We want the dwell tone to be the opposite color of DwellLimit-1.
   itone = (int) (mult * (log(DwellLimit-1) - log_min)) ; // Tone at DwellLimit-1
   itone = itone % 2 ;                                      // Make it binary
   if (CmapNlinear % 2 == 0)   // See comment below if this is not clear
      itone = 1 - itone ;
   dwell_tone = 1 - itone ;  // Make tone at dwell opposite nearest neighbor

   black = (unsigned char) (0.01 * CmapFloor * 255.999) ;
   white = (unsigned char) 255 ;

/*
   Implement the color map.  The output image in raw_image has three bytes per
   pixel as R, G, B, which we will make equal here for true gray levels.
*/

   for (irow=0 ; irow<RowResolution ; irow++) {
      dwell_ptr = dwells + irow * ColResolution ;
      for (icol=0 ; icol<ColResolution ; icol++) {
         raw_ptr = raw_image + (irow * ColResolution + icol) * 3 ; // This image pixel
         if (dwell_ptr[icol] >= DwellLimit)
            itone = dwell_tone ;  // Opposite of next highest
         else if (dwell_ptr[icol] <= CmapNlinear)
            itone = dwell_ptr[icol] % 2 ;
         else {
            itone = (int) (mult * (log(dwell_ptr[icol]) - log_min)) ; // 0 through CmapNlog-1
            itone = itone % 2 ;
            // We want min_dwell (itone=0 as of now) to have opposite color of CmapNlinear
            // In high-dwell areas, min_dwell is usually much greater than CmapNlinear,
            // so it doesn't matter.  But for most larger areas, and if the user
            // specifies CmapNlinear>0, min_dwell=CmapNlinear+1, so it matters very much.
            if (CmapNlinear % 2 == 0)
               itone = 1 - itone ;
            }
         if (CmapStart == 0)
            tone = itone ? white : black ;
         else
            tone = itone ? black : white ;
         raw_ptr[0] = tone ;
         raw_ptr[1] = tone ;
         raw_ptr[2] = tone ;
         }
      }
}
