home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libcnv / libppm3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.8 KB  |  268 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. #include "xp_core.h"/*defines of int32 ect*/
  15. #include "pbmplus.h"
  16. #include "ppm.h"
  17. #include "ppmcmap.h"
  18. #include "libppm.h"
  19.  
  20. #define HASH_SIZE 20023
  21.  
  22. #ifdef PPM_PACKCOLORS
  23. #define ppm_hashpixel(p) ( ( (int16) (p) & 0x7fffffff ) % HASH_SIZE )
  24. #else /*PPM_PACKCOLORS*/
  25. #define ppm_hashpixel(p) ( ( ( (int32) PPM_GETR(p) * 33023 + (int32) PPM_GETG(p) * 30013 + (int32) PPM_GETB(p) * 27011 ) & 0x7fffffff ) % HASH_SIZE )
  26. #endif /*PPM_PACKCOLORS*/
  27.  
  28. colorhist_vector
  29. ppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
  30.     pixel** pixels;
  31.     int16 cols, rows, maxcolors;
  32.     int16* colorsP;
  33.     {
  34.     colorhash_table cht;
  35.     colorhist_vector chv;
  36.  
  37.     cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
  38.     if ( cht == (colorhash_table) 0 )
  39.         return (colorhist_vector) 0;
  40.     chv = ppm_colorhashtocolorhist( cht, maxcolors );
  41.     if (chv==(colorhist_vector)0)
  42.         return (colorhist_vector) 0;
  43.     ppm_freecolorhash( cht );
  44.     return chv;
  45.     }
  46.  
  47. void
  48. ppm_addtocolorhist( chv, colorsP, maxcolors, colorP, value, position )
  49.     colorhist_vector chv;
  50.     pixel* colorP;
  51.     int16* colorsP;
  52.     int16 maxcolors, value, position;
  53.     {
  54.     int16 i, j;
  55.  
  56.     /* Search colorhist for the color. */
  57.     for ( i = 0; i < *colorsP; ++i )
  58.     if ( PPM_EQUAL( chv[i].color, *colorP ) )
  59.         {
  60.         /* Found it - move to new slot. */
  61.         if ( position > i )
  62.         {
  63.         for ( j = i; j < position; ++j )
  64.             chv[j] = chv[j + 1];
  65.         }
  66.         else if ( position < i )
  67.         {
  68.         for ( j = i; j > position; --j )
  69.             chv[j] = chv[j - 1];
  70.         }
  71.         chv[position].color = *colorP;
  72.         chv[position].value = value;
  73.         return;
  74.         }
  75.     if ( *colorsP < maxcolors )
  76.     {
  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.     int16 cols, rows, maxcolors;
  90.     int16* colorsP;
  91.     {
  92.     colorhash_table cht=NULL;
  93.     register pixel* pP=NULL;
  94.     colorhist_list chl=NULL;
  95.     int16 col, row, hash;
  96.  
  97.     cht = ppm_alloccolorhash( );
  98.     if (cht==(colorhash_table)0)
  99.         return NULL;/*JUDGE*/
  100.     *colorsP = 0;
  101.  
  102.     /* Go through the entire image, building a hash table of colors. */
  103.     for ( row = 0; row < rows; ++row )
  104.     for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
  105.         {
  106.         hash = ppm_hashpixel( *pP );
  107.         for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  108.             if ( PPM_EQUAL( chl->ch.color, *pP ) )
  109.                 break;
  110.         if ( chl != (colorhist_list) 0 )
  111.             ++(chl->ch.value);
  112.         else
  113.         {
  114.         if ( ++(*colorsP) > maxcolors )
  115.             {
  116.             ppm_freecolorhash( cht );
  117.             return (colorhash_table) 0;
  118.             }
  119.         chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  120.         if ( chl == 0 )
  121.             return (colorhash_table) 0; /*JUDGE*/
  122.         chl->ch.color = *pP;
  123.         chl->ch.value = 1;
  124.         chl->next = cht[hash];
  125.         cht[hash] = chl;
  126.         }
  127.         }
  128.     
  129.     return cht;
  130.     }
  131.  
  132. colorhash_table
  133. ppm_alloccolorhash( )
  134.     {
  135.     colorhash_table cht=NULL;
  136.     int16 i;
  137.  
  138.     cht = (colorhash_table) malloc( HASH_SIZE * sizeof(colorhist_list) );
  139.     if ( cht == 0 )
  140.         return NULL;/*JUDGE*/
  141.  
  142.     for ( i = 0; i < HASH_SIZE; ++i )
  143.     cht[i] = (colorhist_list) 0;
  144.  
  145.     return cht;
  146.     }
  147.  
  148. int16
  149. ppm_addtocolorhash( cht, colorP, value )
  150.     colorhash_table cht;
  151.     pixel* colorP;
  152.     int16 value;
  153.     {
  154.     register int16 hash=0;
  155.     register colorhist_list chl=NULL;
  156.  
  157.     chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  158.     if ( chl == 0 )
  159.         return -1;
  160.     hash = ppm_hashpixel( *colorP );
  161.     chl->ch.color = *colorP;
  162.     chl->ch.value = value;
  163.     chl->next = cht[hash];
  164.     cht[hash] = chl;
  165.     return 0;
  166.     }
  167.  
  168. colorhist_vector
  169. ppm_colorhashtocolorhist( cht, maxcolors )
  170.     colorhash_table cht;
  171.     int16 maxcolors;
  172.     {
  173.     colorhist_vector chv;
  174.     colorhist_list chl;
  175.     int16 i, j;
  176.  
  177.     /* Now collate the hash table into a simple colorhist array. */
  178.     chv = (colorhist_vector) malloc( maxcolors * sizeof(struct colorhist_item) );
  179.     /* (Leave room for expansion by caller.) */
  180.     if ( chv == (colorhist_vector) 0 )
  181.         return (colorhist_vector)0;/*JUDGE*/
  182.     
  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.     int16 colors;
  202.     {
  203.     colorhash_table cht;
  204.     int16 i, hash;
  205.     pixel color;
  206.     colorhist_list chl;
  207.  
  208.     cht = ppm_alloccolorhash( );
  209.     if (cht==(colorhash_table)0)
  210.         return (colorhash_table)0;
  211.     for ( i = 0; i < colors; ++i )
  212.     {
  213.         color = chv[i].color;
  214.         hash = ppm_hashpixel( color );
  215.         for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  216.             if ( PPM_EQUAL( chl->ch.color, color ) )
  217.                 return (colorhash_table)0;
  218.         chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
  219.         if ( chl == (colorhist_list) 0 )
  220.             return (colorhash_table)0;
  221.         chl->ch.color = color;
  222.         chl->ch.value = i;
  223.         chl->next = cht[hash];
  224.         cht[hash] = chl;
  225.     }
  226.  
  227.     return cht;
  228.     }
  229.  
  230. int16
  231. ppm_lookupcolor( cht, colorP )
  232.     colorhash_table cht;
  233.     pixel* colorP;
  234.     {
  235.     int16 hash;
  236.     colorhist_list chl;
  237.  
  238.     hash = ppm_hashpixel( *colorP );
  239.     for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
  240.     if ( PPM_EQUAL( chl->ch.color, *colorP ) )
  241.         return chl->ch.value;
  242.  
  243.     return -1;
  244.     }
  245.  
  246. void
  247. ppm_freecolorhist( chv )
  248.     colorhist_vector chv;
  249.     {
  250.     free( chv);/*(char*) chv );*/
  251.     }
  252.  
  253. void
  254. ppm_freecolorhash( cht )
  255.     colorhash_table cht;
  256.     {
  257.     int16 i;
  258.     colorhist_list chl, chlnext;
  259.  
  260.     for ( i = 0; i < HASH_SIZE; ++i )
  261.     for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext )
  262.         {
  263.         chlnext = chl->next;
  264.         free (chl); /*free( (char*) chl );*/
  265.         }
  266.     free( cht); /*(char*) cht );*/
  267.     }
  268.