home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PPM / libppm3.c < prev    next >
Text File  |  1997-01-19  |  6KB  |  269 lines

  1. /* libppm3.c - ppm utility library part 3
  2. **
  3. ** Colormap routines.
  4. **
  5. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  6. **
  7. ** Permission to use, copy, modify, and distribute this software and its
  8. ** documentation for any purpose and without fee is hereby granted, provided
  9. ** that the above copyright notice appear in all copies and that both that
  10. ** copyright notice and this permission notice appear in supporting
  11. ** documentation.  This software is provided "as is" without express or
  12. ** implied warranty.
  13. */
  14.  
  15. #include "ppm.h"
  16. #include "ppmcmap.h"
  17. #include "libppm.h"
  18.  
  19. #define HASH_SIZE 20023
  20.  
  21. #ifdef PPM_PACKCOLORS
  22. #define ppm_hashpixel(p) ( ( (int) (p) & 0x7fffffff ) % HASH_SIZE )
  23. #else /*PPM_PACKCOLORS*/
  24. #define ppm_hashpixel(p) ( ( ( (long) PPM_GETR(p) * 33023 + (long) PPM_GETG(p) * 30013 + (long) PPM_GETB(p) * 27011 ) & 0x7fffffff ) % HASH_SIZE )
  25. #endif /*PPM_PACKCOLORS*/
  26.  
  27. colorhist_vector
  28. ppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
  29.     pixel** pixels;
  30.     int cols, rows, maxcolors;
  31.     int* colorsP;
  32.     {
  33.     colorhash_table cht;
  34.     colorhist_vector chv;
  35.  
  36.     cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
  37.     if ( cht == (colorhash_table) 0 )
  38.     return (colorhist_vector) 0;
  39.     chv = ppm_colorhashtocolorhist( cht, maxcolors );
  40.     ppm_freecolorhash( cht );
  41.     return chv;
  42.     }
  43.  
  44. void
  45. ppm_addtocolorhist( chv, colorsP, maxcolors, colorP, value, position )
  46.     colorhist_vector chv;
  47.     pixel* colorP;
  48.     int* colorsP;
  49.     int maxcolors, value, position;
  50.     {
  51.     int i, j;
  52.  
  53.     /* Search colorhist for the color. */
  54.     for ( i = 0; i < *colorsP; ++i )
  55.     if ( PPM_EQUAL( chv[i].color, *colorP ) )
  56.         {
  57.         /* Found it - move to new slot. */
  58.         if ( position > i )
  59.         {
  60.         for ( j = i; j < position; ++j )
  61.             chv[j] = chv[j + 1];
  62.         }
  63.         else if ( position < i )
  64.         {
  65.         for ( j = i; j > position; --j )
  66.             chv[j] = chv[j - 1];
  67.         }
  68.         chv[position].color = *colorP;
  69.         chv[position].value = value;
  70.         return;
  71.         }
  72.     if ( *colorsP < maxcolors )
  73.     {
  74.     /* Didn't find it, but there's room to add it; so do so. */
  75.     for ( i = *colorsP; i > position; --i )
  76.         chv[i] = chv[i - 1];
  77.     chv[position].color = *colorP;
  78.     chv[position].value = value;
  79.     ++(*colorsP);
  80.     }
  81.     }
  82.  
  83. colorhash_table
  84. ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP )
  85.     pixel** pixels;
  86.     int cols, rows, maxcolors;
  87.     int* colorsP;
  88.     {
  89.     colorhash_table cht;
  90.     register pixel* pP;
  91.     colorhist_list chl;
  92.     int col, row, hash;
  93.  
  94.     cht = ppm_alloccolorhash( );
  95.     *colorsP = 0;
  96.  
  97.     /* Go through the entire image, building a hash table of colors. */
  98.     for ( row = 0; row < rows; ++row )
  99.     for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
  100.         {
  101.         hash = ppm_hashpixel( *pP );
  102.         for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  103.         if ( PPM_EQUAL( chl->ch.color, *pP ) )
  104.             break;
  105.         if ( chl != (colorhist_list) 0 )
  106.         ++(chl->ch.value);
  107.         else
  108.         {
  109.         if ( ++(*colorsP) > maxcolors )
  110.             {
  111.             ppm_freecolorhash( cht );
  112.             return (colorhash_table) 0;
  113.             }
  114.         chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  115.         if ( chl == 0 )
  116.             pm_error( "out of memory computing hash table" );
  117. #ifndef OSK
  118.         chl->ch.color = *pP;
  119. #else
  120.         chl->ch.color.r = pP->r;
  121.         chl->ch.color.g = pP->g;
  122.         chl->ch.color.b = pP->b;
  123. #endif
  124.         chl->ch.value = 1;
  125.         chl->next = cht[hash];
  126.         cht[hash] = chl;
  127.         }
  128.         }
  129.     
  130.     return cht;
  131.     }
  132.  
  133. colorhash_table
  134. ppm_alloccolorhash( )
  135.     {
  136.     colorhash_table cht;
  137.     int i;
  138.  
  139.     cht = (colorhash_table) malloc( HASH_SIZE * sizeof(colorhist_list) );
  140.     if ( cht == 0 )
  141.     pm_error( "out of memory allocating hash table" );
  142.  
  143.     for ( i = 0; i < HASH_SIZE; ++i )
  144.     cht[i] = (colorhist_list) 0;
  145.  
  146.     return cht;
  147.     }
  148.  
  149. int
  150. ppm_addtocolorhash( cht, colorP, value )
  151.     colorhash_table cht;
  152.     pixel* colorP;
  153.     int value;
  154.     {
  155.     register int hash;
  156.     register colorhist_list chl;
  157.  
  158.     chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  159.     if ( chl == 0 )
  160.     return -1;
  161.     hash = ppm_hashpixel( *colorP );
  162.     chl->ch.color = *colorP;
  163.     chl->ch.value = value;
  164.     chl->next = cht[hash];
  165.     cht[hash] = chl;
  166.     return 0;
  167.     }
  168.  
  169. colorhist_vector
  170. ppm_colorhashtocolorhist( cht, maxcolors )
  171.     colorhash_table cht;
  172.     int maxcolors;
  173.     {
  174.     colorhist_vector chv;
  175.     colorhist_list chl;
  176.     int i, j;
  177.  
  178.     /* Now collate the hash table into a simple colorhist array. */
  179.     chv = (colorhist_vector) malloc( maxcolors * sizeof(struct colorhist_item) );
  180.     /* (Leave room for expansion by caller.) */
  181.     if ( chv == (colorhist_vector) 0 )
  182.     pm_error( "out of memory generating histogram" );
  183.  
  184.     /* Loop through the hash table. */
  185.     j = 0;
  186.     for ( i = 0; i < HASH_SIZE; ++i )
  187.     for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next )
  188.         {
  189.         /* Add the new entry. */
  190.         chv[j] = chl->ch;
  191.         ++j;
  192.         }
  193.  
  194.     /* All done. */
  195.     return chv;
  196.     }
  197.  
  198. colorhash_table
  199. ppm_colorhisttocolorhash( chv, colors )
  200.     colorhist_vector chv;
  201.     int colors;
  202.     {
  203.     colorhash_table cht;
  204.     int i, hash;
  205.     pixel color;
  206.     colorhist_list chl;
  207.  
  208.     cht = ppm_alloccolorhash( );
  209.  
  210.     for ( i = 0; i < colors; ++i )
  211.     {
  212.     color = chv[i].color;
  213.     hash = ppm_hashpixel( color );
  214.     for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  215.         if ( PPM_EQUAL( chl->ch.color, color ) )
  216.         pm_error(
  217.             "same color found twice - %d %d %d", PPM_GETR(color),
  218.             PPM_GETG(color), PPM_GETB(color) );
  219.     chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  220.     if ( chl == (colorhist_list) 0 )
  221.         pm_error( "out of memory" );
  222.     chl->ch.color = color;
  223.     chl->ch.value = i;
  224.     chl->next = cht[hash];
  225.     cht[hash] = chl;
  226.     }
  227.  
  228.     return cht;
  229.     }
  230.  
  231. int
  232. ppm_lookupcolor( cht, colorP )
  233.     colorhash_table cht;
  234.     pixel* colorP;
  235.     {
  236.     int hash;
  237.     colorhist_list chl;
  238.  
  239.     hash = ppm_hashpixel( *colorP );
  240.     for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  241.     if ( PPM_EQUAL( chl->ch.color, *colorP ) )
  242.         return chl->ch.value;
  243.  
  244.     return -1;
  245.     }
  246.  
  247. void
  248. ppm_freecolorhist( chv )
  249.     colorhist_vector chv;
  250.     {
  251.     free( (char*) chv );
  252.     }
  253.  
  254. void
  255. ppm_freecolorhash( cht )
  256.     colorhash_table cht;
  257.     {
  258.     int i;
  259.     colorhist_list chl, chlnext;
  260.  
  261.     for ( i = 0; i < HASH_SIZE; ++i )
  262.     for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext )
  263.         {
  264.         chlnext = chl->next;
  265.         free( (char*) chl );
  266.         }
  267.     free( (char*) cht );
  268.     }
  269.