home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / source / dkbsrc.lzh / PALETTE.C < prev    next >
C/C++ Source or Header  |  1990-07-07  |  6KB  |  210 lines

  1. /*****************************************************************************
  2. *
  3. *                                   dumproto.h
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This file contains routines to choose colour palettes for DumpToIFF
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *
  44. *****************************************************************************/
  45.  
  46. #include <stdio.h>
  47. #include <exec/types.h>
  48. #include "showprioq.h"
  49. #include "dumptoiff.h"
  50. #include "dumproto.h"
  51.  
  52. ULONG last_red = 0, last_green = 0, last_blue = 0;
  53. int Close_Threshold;
  54.  
  55. #define absdif(x,y) ((x>y) ? (x-y):(y-x))
  56. #define Make_Colour(x, y, z) ((x & 0xF) << 8) + ((y & 0xF) << 4) + (z & 0xF)
  57.  
  58. #define extract_red(x) ((x & 0xF00) >> 8)
  59. #define extract_green(x) ((x & 0x0F0) >> 4)
  60. #define extract_blue(x) (x & 0x00F)
  61.  
  62. struct prioq_struct *Colour_q;
  63. struct prioq_struct *pq_new();
  64.  
  65.  
  66. extern UWORD ColourTbl[16];
  67.  
  68. void reset_colours ()
  69.   {
  70.   last_red = last_green = last_blue = 0;
  71.   }
  72.  
  73. int closeness(x, y)
  74.   int x, y;
  75.   {
  76.   int red, blue, green;
  77.  
  78.   red = absdif(extract_red(x), extract_red(y));
  79.   blue = absdif (extract_blue(x), extract_blue(y));
  80.   green = absdif(extract_green(x), extract_green(y));
  81.   return (red+blue+green);
  82.   }
  83.  
  84. void start_recording_colours ()
  85.   {
  86.   Colour_q = pq_new (256, 4096);
  87.   if (Colour_q == NULL)
  88.     exit (0);
  89.  
  90.   reset_colours();
  91.   }
  92.  
  93. void record_colours (new_red, new_green, new_blue)
  94.   int new_red, new_green, new_blue;
  95.   {
  96.   LONG delta_red, delta_green, delta_blue, match_quality;
  97.  
  98.   delta_red = absdif (new_red, last_red);
  99.   delta_green = absdif (new_green, last_green);
  100.   delta_blue = absdif (new_blue, last_blue);
  101.  
  102.   if (delta_red > delta_green)
  103.     if (delta_red > delta_blue) {
  104.       last_red = new_red;
  105.       match_quality = delta_green + delta_blue;
  106.       }
  107.     else {
  108.       last_blue = new_blue;
  109.       match_quality = delta_green + delta_red;
  110.       }
  111.   else
  112.     if (delta_green > delta_blue)
  113.       {
  114.       last_green = new_green;
  115.       match_quality = delta_red + delta_blue;
  116.       }
  117.     else {
  118.       last_blue = new_blue;
  119.       match_quality = delta_green + delta_red;
  120.       }
  121.  
  122.     if (match_quality != 0)
  123.       pq_add (Colour_q, match_quality,
  124.               Make_Colour (new_red, new_green, new_blue));
  125.   }      
  126.  
  127. void choose_palette()
  128.   {
  129.   int i, j, colour, min_distance, temp_distance;
  130.   struct prioq_struct *post_pq;
  131.  
  132.   post_pq = pq_new (32, 4096);
  133.  
  134.   ColourTbl[0] = Make_Colour (0, 0, 0);
  135.   for (i=1 ; i < 16 ;) {
  136.     if (pq_get_highest_index (Colour_q) > pq_get_highest_index (post_pq))
  137.       {
  138.       colour = pq_get_highest_value (Colour_q);
  139.       pq_delete_highest (Colour_q);
  140.  
  141.       min_distance = 255;
  142.       for (j = 0 ; j < i ; j++)
  143.        if ((temp_distance = closeness (ColourTbl[j], colour)) < min_distance)
  144.          min_distance = temp_distance;
  145.  
  146.       if (min_distance < 5)
  147.         pq_add (post_pq, min_distance, colour);
  148.       else
  149.        ColourTbl[i++] = colour;
  150.       }
  151.     else
  152.       {
  153.       ColourTbl[i++] = pq_get_highest_value (post_pq);
  154.       pq_delete_highest (post_pq);
  155.       }
  156.     }
  157.   pq_free (Colour_q);
  158.   pq_free (post_pq);
  159.   }
  160.  
  161. int best_colour (new_red, new_blue, new_green)
  162.   int new_red, new_blue, new_green;
  163.   {
  164.   int i, match_quality, best_match, colour,
  165.       delta_red, delta_green, delta_blue, temp_match_quality;
  166.  
  167.   delta_red = absdif (new_red, last_red);
  168.   delta_green = absdif (new_green, last_green);
  169.   delta_blue = absdif (new_blue, last_blue);
  170.  
  171.   if (delta_red > delta_green)
  172.     if (delta_red > delta_blue) {
  173.       last_red = new_red;
  174.       colour = 0x20 + new_red;
  175.       match_quality = delta_green + delta_blue;
  176.       }
  177.     else {
  178.       last_blue = new_blue;
  179.       colour = 0x10 + new_blue;
  180.       match_quality = delta_green + delta_red;
  181.       }
  182.   else
  183.     if (delta_green > delta_blue)
  184.       {
  185.       last_green = new_green;
  186.       colour = 0x30 + new_green;
  187.       match_quality = delta_red + delta_blue;
  188.       }
  189.     else {
  190.       last_blue = new_blue;
  191.       colour = 0x10 + new_blue;
  192.       match_quality = delta_green + delta_red;
  193.       }
  194.  
  195.   if (match_quality != 0)
  196.     for (i = 0 ; i < 16 ; i++)
  197.       if ((temp_match_quality =
  198.            closeness (ColourTbl[i],
  199.             Make_Colour (new_red, new_green, new_blue)))
  200.           < match_quality) {
  201.         match_quality = temp_match_quality;
  202.         colour = i;
  203.         last_red = extract_red (ColourTbl[i]);
  204.         last_green = extract_green (ColourTbl[i]);
  205.         last_blue = extract_blue (ColourTbl[i]);
  206.         }
  207.   return (colour);
  208.   }
  209.  
  210.