home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmbrighten.c < prev    next >
C/C++ Source or Header  |  1993-10-27  |  7KB  |  280 lines

  1. /* ppmbrighten.c - allow user control over Value and Saturation of PPM file
  2. **
  3. ** Copyright (C) 1989 by Jef Poskanzer.
  4. ** Copyright (C) 1990 by Brian Moffet.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. */
  13.  
  14. #include "ppm.h"
  15.  
  16. static int GetHSV ARGS((long r, long g, long b, long *h, long *s, long *v));
  17. static int GetRGB ARGS((long h, long s, long v, long *r, long *g, long *b));
  18.  
  19. #define MULTI   1000
  20. #define FIND_MINMAX     1
  21. #define SET_VALUE       2
  22. #define SET_SATUR       4
  23.  
  24. static int GetHSV( r, g, b, h, s, v )
  25.     long r, g, b;
  26.     long *h, *s, *v;
  27. {
  28.     long t;
  29.  
  30.     *v = max( r, max( g, b ) );
  31.  
  32.     t = min( r, min( g, b ) );
  33.  
  34.     if ( *v == 0 )
  35.         *s = 0;
  36.     else
  37.         *s = ( (*v - t)*MULTI ) / *v;
  38.  
  39.     if ( *s == 0 )
  40.         *h = 0;
  41.     else
  42.     {
  43.         long cr, cg, cb;
  44.         cr = (MULTI * ( *v - r ))/( *v - t );
  45.         cg = (MULTI * ( *v - g ))/( *v - t );
  46.         cb = (MULTI * ( *v - b ))/( *v - t );
  47.  
  48.         if ( r == *v )
  49.             *h = cb - cg;
  50.  
  51.         if ( g == *v )
  52.             *h = (2*MULTI) + cr - cb;
  53.  
  54.         if ( b == *v )
  55.             *h = (4*MULTI) + cg - cr;
  56.  
  57.         *h = *h * 60;
  58.         if ( *h < 0 )
  59.             *h += (360 * MULTI);
  60.     }
  61. }
  62.  
  63. static int
  64.     GetRGB( h, s, v, r, g, b )
  65. long h, s, v;
  66. long *r, *g, *b;
  67. {
  68.     if ( s == 0 )
  69.     {
  70.         *r = v;
  71.         *g = v;
  72.         *b = v;
  73.     } else {
  74.         long f, m, n, k;
  75.         long i;
  76.  
  77.         if (h == (360 * MULTI))
  78.             h = 0;
  79.         h = h / 60;
  80.         i = (h - (h % MULTI));
  81.         f = h - i;
  82.         m = (v * (MULTI - s)) / MULTI;
  83.         n = (v * (MULTI - (s * f)/MULTI)) / MULTI;
  84.         k = (v * (MULTI - (s * (MULTI - f))/MULTI)) / MULTI;
  85.  
  86.         switch (i)
  87.         {
  88.         case 0:
  89.             *r = v;
  90.             *g = k;
  91.             *b = m;
  92.             break;
  93.         case MULTI:
  94.             *r = n;
  95.             *g = v;
  96.             *b = m;
  97.             break;
  98.         case (2*MULTI):
  99.             *r = m;
  100.             *g = v;
  101.             *b = k;
  102.             break;
  103.         case (3*MULTI):
  104.             *r = m;
  105.             *g = n;
  106.             *b = v;
  107.             break;
  108.         case (4*MULTI):
  109.             *r = k;
  110.             *g = m;
  111.             *b = v;
  112.             break;
  113.         case (5*MULTI):
  114.             *r = v;
  115.             *g = m;
  116.             *b = n;
  117.             break;
  118.         }
  119.     }
  120. }
  121.  
  122. int
  123. main( argc, argv )
  124.     int argc;
  125.     char *argv[];
  126. {
  127.     FILE *fp = stdin;
  128.     extern char *optarg;
  129.     extern int optind;
  130.     int value = 100, saturation = 100, c, error = 0;
  131.     int min_value, max_value;
  132.     int flags = 0;
  133.     int argn;
  134.     char *usage = "[-saturation <+-s>] [-value <+-v>] [-normalize] [<ppmfile>]";
  135.     pixel *pixelP;
  136.     pixval maxval;
  137.     int rows, cols, format, indexv;
  138.  
  139.  
  140.     ppm_init(&argc, argv);
  141.  
  142.     argn = 1;
  143.     while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  144.         {
  145.         if( pm_keymatch( argv[argn], "-saturation", 2 ) )
  146.             {
  147.             if( ++argn > argc )
  148.                 pm_usage( usage );
  149.             flags |= SET_SATUR;
  150.             saturation = 100 + atoi( argv[argn] );
  151.             }
  152.         else
  153.         if( pm_keymatch( argv[argn], "-value", 2 ) )
  154.             {
  155.             if( ++argn > argc )
  156.                 pm_usage( usage );
  157.             flags |= SET_SATUR;
  158.             value = 100 + atoi( argv[argn] );
  159.             }
  160.         else
  161.         if( pm_keymatch( argv[argn], "-normalize", 2 ) )
  162.             {
  163.             flags |= FIND_MINMAX;
  164.             }
  165.         else
  166.             pm_usage(usage);
  167.         ++argn;
  168.         }
  169.  
  170.     if (value < 0) value = 0;
  171.  
  172.     if (saturation < 0) saturation = 0;
  173.  
  174.     if( argn != argc )
  175.         {
  176.         fp = pm_openr( argv[argn] );
  177.         ++argn;
  178.         }
  179.     else
  180.         fp = stdin;
  181.  
  182.  
  183.  
  184.     if (flags & FIND_MINMAX)
  185.     {
  186.         ppm_readppminit( fp, &cols, &rows, &maxval, &format );
  187.         pixelP = ppm_allocrow( cols );
  188.         max_value = 0;
  189.         min_value = MULTI;
  190.         for (indexv = 0; indexv < rows; indexv++)
  191.         {
  192.             int i;
  193.             ppm_readppmrow( fp, pixelP, cols, maxval, format );
  194.             for (i = 0; i < cols; i++)
  195.             {
  196.                 int r, g, b;
  197.                 long R, G, B, H, S, V;
  198.  
  199.                 r = PPM_GETR( pixelP[i] );
  200.                 g = PPM_GETG( pixelP[i] );
  201.                 b = PPM_GETB( pixelP[i] );
  202.  
  203.                 R = (MULTI * r + maxval - 1) / maxval;
  204.                 G = (MULTI * g + maxval - 1) / maxval;
  205.                 B = (MULTI * b + maxval - 1) / maxval;
  206.  
  207.                 GetHSV( R, G, B, &H, &S, &V );
  208.                 if ( V > max_value)     max_value = V;
  209.                 if ( V < min_value)     min_value = V;
  210.             }
  211.         }
  212.         ppm_freerow( pixelP );
  213.         pm_message("Min is %4d\tMax = %4d", min_value, max_value );
  214.         rewind( fp );
  215.     }
  216.  
  217.     ppm_readppminit( fp, &cols, &rows, &maxval, &format );
  218.  
  219.     ppm_writeppminit( stdout, cols, rows, maxval, 0 );
  220.  
  221.     pixelP = ppm_allocrow( cols );
  222.  
  223.     if (pixelP == NULL)
  224.         pm_error( "Error allocating Pixel row" );
  225.  
  226.     for (indexv = 0; indexv < rows; indexv++)
  227.     {
  228.         int i;
  229.         ppm_readppmrow( fp, pixelP, cols, maxval, format );
  230.         for (i = 0; i < cols; i++)
  231.         {
  232.             int r, g, b;
  233.             long R, G, B, H, S, V;
  234.  
  235.             r = PPM_GETR( pixelP[i] );
  236.             g = PPM_GETG( pixelP[i] );
  237.             b = PPM_GETB( pixelP[i] );
  238.  
  239.             R = (MULTI * r + maxval - 1) / maxval;
  240.             G = (MULTI * g + maxval - 1) / maxval;
  241.             B = (MULTI * b + maxval - 1) / maxval;
  242.  
  243.             GetHSV( R, G, B, &H, &S, &V );
  244.  
  245.             if (flags & FIND_MINMAX)
  246.             {
  247.                 V -= min_value;
  248.                 V = (V * MULTI) /
  249.                     (MULTI - (min_value+MULTI-max_value));
  250.             }
  251.  
  252.             S = ( S * saturation ) / 100;
  253.             V = ( V * value ) / 100;
  254.  
  255.             if (V > MULTI)
  256.                 V = MULTI;
  257.             if (S > MULTI)
  258.                 S = MULTI;
  259.  
  260.             GetRGB( H, S, V, &R, &G, &B );
  261.  
  262.             r = (R * maxval) / MULTI;
  263.             g = (G * maxval) / MULTI;
  264.             b = (B * maxval) / MULTI;
  265.  
  266.             PPM_ASSIGN( pixelP[i], r, g, b );
  267.         }
  268.  
  269.         ppm_writeppmrow( stdout, pixelP, cols, maxval, 0 );
  270.     }
  271.     ppm_freerow( pixelP );
  272.  
  273.     pm_close( fp );
  274. }
  275.  
  276. /*
  277.   #define       min(x,y)        ((x < y) ? x : y)
  278.   #define       max(x,y)        ((x > y) ? x : y)
  279.   */
  280.