home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Anwendungen / Kurztests / PBM / ILBMTOPPM.LHA / src / libcmap2.c < prev    next >
C/C++ Source or Header  |  1994-12-16  |  6KB  |  239 lines

  1. /* libcmap2.c - support routines for color rows
  2. **
  3. ** Copyright (C) 1994 Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
  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 "ppmcmap2.h"
  14.  
  15.  
  16. colorhash_table
  17. ppm_colorrowtocolorhash(colorrow, ncolors)
  18.     pixel *colorrow;
  19.     int ncolors;
  20. {
  21.     colorhash_table cht;
  22.     int i;
  23.  
  24.     cht = ppm_alloccolorhash();
  25.     for( i = 0; i < ncolors; i++ ) {
  26.         if( ppm_lookupcolor(cht, &colorrow[i]) < 0 ) {
  27.             if( ppm_addtocolorhash(cht, &colorrow[i], i) < 0 )
  28.                 pm_error("out of memory adding to hash table");
  29.         }
  30.     }
  31.     return cht;
  32. }
  33.  
  34.  
  35. pixel *
  36. ppm_computecolorrow(pixels, cols, rows, maxcolors, ncolorsP)
  37.     pixel **pixels;
  38.     int cols, rows, maxcolors;
  39.     int *ncolorsP;
  40. {
  41.     int ncolors, row, col;
  42.     colorhash_table cht;
  43.     pixel *pixrow;
  44.  
  45.     pixrow = ppm_allocrow(maxcolors);
  46.     cht = ppm_alloccolorhash(); ncolors = 0;
  47.     for( row = 0; row < rows; row++ ) {
  48.         for( col = 0; col < cols; col++ ) {
  49.             if( ppm_lookupcolor(cht, &pixels[row][col]) < 0 ) {
  50.                 if( ncolors >= maxcolors ) {
  51.                     ppm_freerow(pixrow);
  52.                     pixrow = (pixel *)0;
  53.                     ncolors = -1;
  54.                     goto fail;
  55.                 }
  56.                 if( ppm_addtocolorhash(cht, &pixels[row][col], ncolors) < 0 )
  57.                     pm_error("out of memory adding to hash table");
  58.                 pixrow[ncolors] = pixels[row][col];
  59.                 ++ncolors;
  60.             }
  61.         }
  62.     }
  63. fail:
  64.     ppm_freecolorhash(cht);
  65.  
  66.     *ncolorsP = ncolors;
  67.     return pixrow;
  68. }
  69.  
  70.  
  71. pixel *
  72. ppm_mapfiletocolorrow(file, maxcolors, ncolorsP, maxvalP)
  73.     FILE *file;
  74.     int maxcolors;
  75.     int *ncolorsP;
  76.     pixval *maxvalP;
  77. {
  78.     int cols, rows, format, row, col, ncolors;
  79.     pixel *pixrow, *temprow;
  80.     colorhash_table cht;
  81.  
  82.     pixrow = ppm_allocrow(maxcolors);
  83.  
  84.     ppm_readppminit(file, &cols, &rows, maxvalP, &format);
  85.     temprow = ppm_allocrow(cols);
  86.     cht = ppm_alloccolorhash(); ncolors = 0;
  87.     for( row = 0; row < rows; row++ ) {
  88.         ppm_readppmrow(file, temprow, cols, *maxvalP, format);
  89.         for( col = 0; col < cols; col++ ) {
  90.             if( ppm_lookupcolor(cht, &temprow[col]) < 0 ) {
  91.                 if( ncolors >= maxcolors ) {
  92.                     ppm_freerow(pixrow);
  93.                     pixrow = (pixel *)0;
  94.                     ncolors = -1;
  95.                     goto fail;
  96.                 }
  97.                 if( ppm_addtocolorhash(cht, &temprow[col], ncolors) < 0 )
  98.                     pm_error("out of memory adding to hash table");
  99.                 pixrow[ncolors] = temprow[col];
  100.                 ++ncolors;
  101.             }
  102.         }
  103.     }
  104. fail:
  105.     ppm_freecolorhash(cht);
  106.     ppm_freerow(temprow);
  107.  
  108.     *ncolorsP = ncolors;
  109.     return pixrow;
  110. }
  111.  
  112.  
  113. static int
  114. pixel_cmp(a, b)
  115.     void *a, *b;
  116. {
  117.     pixel *p1 = (pixel *)a, *p2 = (pixel *)b;
  118.     int diff;
  119.  
  120.     diff = PPM_GETR(*p1) - PPM_GETR(*p2);
  121.     if( diff == 0 ) {
  122.         diff = PPM_GETG(*p1) - PPM_GETG(*p2);
  123.         if( diff == 0 )
  124.             diff = PPM_GETB(*p1) - PPM_GETB(*p2);
  125.     }
  126.     return diff;
  127. }
  128.  
  129. static int (*custom_cmp) ARGS((pixel *, pixel *));
  130.  
  131. static int
  132. custom_stub(a, b)
  133.     void *a, *b;
  134. {
  135.     return (*custom_cmp)((pixel *)a, (pixel *)b);
  136. }
  137.  
  138.  
  139. void
  140. ppm_sortcolorrow(colorrow, ncolors, cmpfunc)
  141.     pixel *colorrow;
  142.     int ncolors;
  143.     int (*cmpfunc) ARGS((pixel *, pixel *));
  144. {
  145.     if( cmpfunc ) {
  146.         custom_cmp = cmpfunc;
  147.         qsort((void *)colorrow, ncolors, sizeof(pixel), custom_stub);
  148.     }
  149.     else
  150.         qsort((void *)colorrow, ncolors, sizeof(pixel), pixel_cmp);
  151. }
  152.  
  153.  
  154.  
  155. int
  156. ppm_addtocolorrow(colorrow, ncolorsP, maxcolors, pixelP)
  157.     pixel *colorrow;
  158.     int *ncolorsP;
  159.     int maxcolors;
  160.     pixel *pixelP;
  161. {
  162.     int i;
  163.     pixval r, g, b;
  164.  
  165.     r = PPM_GETR(*pixelP);
  166.     g = PPM_GETG(*pixelP);
  167.     b = PPM_GETB(*pixelP);
  168.  
  169.     for( i = 0; i < *ncolorsP; i++ ) {
  170.         if( PPM_GETR(colorrow[i]) == r &&
  171.             PPM_GETG(colorrow[i]) == g &&
  172.             PPM_GETB(colorrow[i]) == b )
  173.                 return i;
  174.     }
  175.  
  176.     i = *ncolorsP;
  177.     if( i >= maxcolors )
  178.         return -1;
  179.     colorrow[i] = *pixelP;
  180.     ++*ncolorsP;
  181.     return i;
  182. }
  183.  
  184.  
  185. int
  186. ppm_findclosestcolor(colormap, ncolors, pP)
  187.     pixel *colormap;
  188.     int ncolors;
  189.     pixel *pP;
  190. {
  191.     /* Search colormap for closest match.       */
  192.     /* algorithm taken from ppmquant.c   -IUW   */
  193.     register int i, r1, g1, b1;
  194.     int ind;
  195.     long dist;
  196.  
  197.     r1 = PPM_GETR(*pP);
  198.     g1 = PPM_GETG(*pP);
  199.     b1 = PPM_GETB(*pP);
  200.     dist = 2000000000;
  201.     for( i = 0; i < ncolors; i++ ) {
  202.         register int r2, g2, b2;
  203.         long newdist;
  204.  
  205.         r2 = PPM_GETR(colormap[i]);
  206.         g2 = PPM_GETG(colormap[i]);
  207.         b2 = PPM_GETB(colormap[i]);
  208.         newdist = ( r1 - r2 ) * ( r1 - r2 ) +
  209.                   ( g1 - g2 ) * ( g1 - g2 ) +
  210.                   ( b1 - b2 ) * ( b1 - b2 );
  211.  
  212.         if( newdist < dist ) {
  213.             ind = i;
  214.             dist = newdist;
  215.         }
  216.     }
  217.     return ind;
  218. }
  219.  
  220.  
  221. void
  222. #if __STDC__
  223. ppm_colorrowtomapfile(FILE *ofp, pixel *colormap, int ncolors, pixval maxval)
  224. #else
  225. ppm_colorrowtomapfile(ofp, colormap, ncolors, maxval)
  226.     FILE *ofp;
  227.     pixel *colormap;
  228.     int ncolors;
  229.     pixval maxval;
  230. #endif
  231. {
  232.     int i;
  233.  
  234.     ppm_writeppminit(ofp, ncolors, 1, maxval, 1);
  235.     for( i = 0; i < ncolors; i++ )
  236.         ppm_writeppmrow(ofp, &colormap[i], 1, maxval, 1);
  237. }
  238.  
  239.