home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11.lha / ccs-lib / lib / libppm3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-01  |  5.7 KB  |  237 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. % Modified:    Jin Guojun
  15. % Date:    Sat, Feb 15, 1992
  16. % ITG - Lawrence Berkeley Laboratory
  17. */
  18.  
  19. #include "ppm.h"
  20. #include "ppmcmap.h"
  21. #include "libppm.h"
  22.  
  23. static    int    hash_size;
  24.  
  25. /*    #define HASH_SIZE 20023    */
  26. #define HASH_SIZE    6553
  27.  
  28. #ifdef    PPM_PACKCOLORS
  29. #define    ppm_hashpixel(p)    ( ((int)(p) & 0x7fffffff) % hash_size )
  30. #else
  31. #define ppm_hashpixel(p)    ( ( ((long)PPM_GETR(p) * 33023 + \
  32.     (long)PPM_GETG(p) * 30013 + (long)PPM_GETB(p) * 27011) & 0x7fffffff) \
  33.     % hash_size )
  34. #endif    PPM_PACKCOLORS
  35.  
  36. colorhist_vector
  37. ppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
  38. pixel    **pixels;
  39. int    cols, rows, maxcolors;
  40. int    *colorsP;
  41. {
  42. colorhist_vector chv;
  43. colorhash_table    cht =
  44.     ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
  45.  
  46.     if (cht == (colorhash_table) 0)
  47.     return (colorhist_vector) 0;
  48.     chv = ppm_colorhashtocolorhist( cht, maxcolors );
  49.     ppm_freecolorhash( cht );
  50. return chv;
  51. }
  52.  
  53. void
  54. ppm_addtocolorhist( chv, colorsP, maxcolors, colorP, value, position )
  55. colorhist_vector chv;
  56. pixel*    colorP;
  57. int*    colorsP;
  58. int    maxcolors, value, position;
  59. {
  60. int    i, j;
  61.  
  62.     /* Search colorhist for the color. */
  63.     for (i=0; i < *colorsP; ++i)
  64.     if ( PPM_EQUAL(chv[i].color, *colorP) )    { /* Found it - move to new slot. */
  65.         if ( position > i )    {
  66.         for ( j = i; j < position; ++j )
  67.             chv[j] = chv[j + 1];
  68.         }
  69.         else if ( position < i )
  70.         for ( j = i; j > position; --j )
  71.             chv[j] = chv[j - 1];
  72.         chv[position].color = *colorP;
  73.         chv[position].value = value;
  74.         return;
  75.     }
  76.     if ( *colorsP < maxcolors )    {
  77.     /* Didn't find it, but there's room to add it; so do so. */
  78.     for (i = *colorsP; i > position; i--)
  79.         chv[i] = chv[i - 1];
  80.     chv[position].color = *colorP;
  81.     chv[position].value = value;
  82.     ++(*colorsP);
  83.     }
  84. }
  85.  
  86. colorhash_table
  87. ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP )
  88. pixel**    pixels;
  89. int    cols, rows, maxcolors;
  90. int*    colorsP;
  91. {
  92. colorhash_table    cht;
  93. register pixel*    pP;
  94. colorhist_list    chl;
  95. int    col, row, hash;
  96.  
  97.     cht = ppm_alloccolorhash(HASH_SIZE);
  98.     *colorsP = 0;
  99.  
  100.     /* Go through the entire image, building a hash table of colors. */
  101.     for (row=0; row < rows; row++)
  102.     for (col=0, pP = pixels[row]; col < cols; col++, pP++)    {
  103.         hash = ppm_hashpixel( *pP );
  104.         for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  105.         if ( PPM_EQUAL( chl->ch.color, *pP ) )
  106.             break;
  107.         if ( chl != (colorhist_list) 0 )
  108.         ++(chl->ch.value);
  109.         else {
  110.         if ( ++(*colorsP) > maxcolors )    {
  111.             ppm_freecolorhash( cht );
  112.             return (colorhash_table) 0;
  113.         }
  114.         chl = (colorhist_list) zalloc(sizeof(struct colorhist_list_item),
  115.             1, "computing hash table");
  116.         chl->ch.color = *pP;
  117.         chl->ch.value = 1;
  118.         chl->next = cht[hash];
  119.         cht[hash] = chl;
  120.         }
  121.     }
  122. return cht;
  123. }
  124.  
  125. colorhash_table
  126. ppm_alloccolorhash(hash_list_len)
  127. {
  128. colorhash_table    cht = (colorhash_table) zalloc(hash_list_len,
  129.     sizeof(colorhist_list), "hash table");
  130. hash_size = hash_list_len;
  131. return cht;
  132. }
  133.  
  134. ppm_addtocolorhash( cht, colorP, value )
  135. colorhash_table    cht;
  136. pixel*    colorP;
  137. int    value;
  138. {
  139. register int    hash;
  140. register colorhist_list    chl =
  141.     (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  142.     if (chl == 0)
  143.     return -1;
  144.     hash = ppm_hashpixel( *colorP );
  145.     chl->ch.color = *colorP;
  146.     chl->ch.value = value;
  147.     chl->next = cht[hash];
  148.     cht[hash] = chl;
  149. return    0;
  150. }
  151.  
  152. colorhist_vector
  153. ppm_colorhashtocolorhist( cht, maxcolors )
  154. colorhash_table    cht;
  155. int    maxcolors;
  156. {
  157. register int    i, j;
  158. register colorhist_list    chl;
  159. register colorhist_vector chv =
  160.  
  161.     /* Now collate the hash table into a simple colorhist array. */
  162.     (colorhist_vector) zalloc(maxcolors, sizeof(struct colorhist_item),
  163.         "histogram" );
  164.  
  165.     /* Loop through the hash table. */
  166.     for (i=j=0; i < HASH_SIZE; i++)
  167.     for (chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next)
  168.         /* Add the new entry. */
  169.         chv[j++] = chl->ch;
  170. return    chv;    /* All done. */
  171. }
  172.  
  173. colorhash_table
  174. ppm_colorhisttocolorhash(chv, colors)
  175. colorhist_vector    chv;
  176. int    colors;
  177. {
  178. int    i, hash;
  179. pixel    color;
  180. colorhist_list    chl;
  181. colorhash_table    cht = ppm_alloccolorhash(colors);
  182.  
  183.     for (i=0; i < colors; ++i)    {
  184.     color = chv[i].color;
  185.     hash = ppm_hashpixel( color );
  186.     for (chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next)
  187.         if (PPM_EQUAL(chl->ch.color, color)) {
  188.         prgmerr(DEBUGANY,
  189.             "same color found twice - %d %d %d", PPM_GETR(color),
  190.                 PPM_GETG(color), PPM_GETB(color));
  191.         return    NULL;
  192.     }
  193.     chl = (colorhist_list) zalloc(sizeof(struct colorhist_list_item), 1,
  194.         "hist_to_hash");
  195.     chl->ch.color = color;
  196.     chl->ch.value = i;
  197.     chl->next = cht[hash];
  198.     cht[hash] = chl;
  199.     }
  200. return cht;
  201. }
  202.  
  203. ppm_lookupcolor( cht, colorP )
  204. colorhash_table cht;
  205. pixel* colorP;
  206. {
  207. colorhist_list chl;
  208. int    hash = ppm_hashpixel( *colorP );
  209.     for (chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next)
  210.     if (PPM_EQUAL(chl->ch.color, *colorP))
  211.         return chl->ch.value;
  212. return -1;
  213. }
  214.  
  215. void
  216. ppm_freecolorhist( chv )
  217. colorhist_vector chv;
  218. {
  219.     free( (char*) chv );
  220. }
  221.  
  222. void
  223. ppm_freecolorhash( cht )
  224. colorhash_table cht;
  225. {
  226. register colorhist_list    chl, chlnext;
  227. register int    i = pointer_buffer_size(cht) / sizeof(chl);
  228.     if (hash_size < i && (i-2 < hash_size || i-16 > hash_size))
  229.         i = hash_size;
  230.     while (i--)
  231.     for (chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext)    {
  232.         chlnext = chl->next;
  233.         free( (char*)chl );
  234.     }
  235.     free(cht);
  236. }
  237.