home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / ppm / libppm3.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  6KB  |  251 lines

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