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

  1. /* libpnm3.c - pnm 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 "pnm.h"
  15.  
  16. #ifdef PPM
  17. #include "ppm.h"
  18. #include "libppm.h"
  19. #endif PPM
  20.  
  21. #ifdef PGM
  22. #include "pgm.h"
  23. #include "libpgm.h"
  24. #endif PGM
  25.  
  26. #ifdef PBM
  27. #include "pbm.h"
  28. #include "libpbm.h"
  29. #endif PBM
  30.  
  31. xel
  32. pnm_backgroundxel( xels, cols, rows, maxval, format )
  33. xel **xels;
  34. xelval maxval;
  35. int cols, rows, format;
  36.     {
  37.     xel bgxel, ul, ur, ll, lr;
  38. #ifdef PGM
  39.     gray gul, gur, gll, glr;
  40. #endif PGM
  41.  
  42.     /* Guess a good background value. */
  43.     ul = xels[0][0];
  44.     ur = xels[0][cols-1];
  45.     ll = xels[rows-1][0];
  46.     lr = xels[rows-1][cols-1];
  47.  
  48.     /* First check for three corners equal. */
  49.     if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, ll ) )
  50.     bgxel = ul;
  51.     else if ( PNM_EQUAL( ul, ur ) && PNM_EQUAL( ur, lr ) )
  52.     bgxel = ul;
  53.     else if ( PNM_EQUAL( ul, ll ) && PNM_EQUAL( ll, lr ) )
  54.     bgxel = ul;
  55.     else if ( PNM_EQUAL( ur, ll ) && PNM_EQUAL( ll, lr ) )
  56.     bgxel = ur;
  57.     /* Nope, check for two corners equal. */
  58.     else if ( PNM_EQUAL( ul,  ur ) || PNM_EQUAL( ul,  ll ) ||
  59.           PNM_EQUAL( ul,  lr ) )
  60.     bgxel = ul;
  61.     else if ( PNM_EQUAL( ur,  ll ) || PNM_EQUAL( ul,  lr ) )
  62.     bgxel = ur;
  63.     else if ( PNM_EQUAL( ll,  lr ) )
  64.     bgxel = ll;
  65.     else
  66.     {
  67.     /* Nope, we have to average the four corners.  This breaks the
  68.     ** rules of pnm, but oh well.  Let's try to do it portably. */
  69.     switch ( format )
  70.         {
  71. #ifdef PPM
  72.         case PPM_FORMAT:
  73.         case RPPM_FORMAT:
  74.         PPM_ASSIGN( bgxel,
  75.         PPM_GETR(ul) + PPM_GETR(ur) + PPM_GETR(ll) + PPM_GETR(lr) / 4,
  76.         PPM_GETG(ul) + PPM_GETG(ur) + PPM_GETG(ll) + PPM_GETG(lr) / 4,
  77.         PPM_GETB(ul) + PPM_GETB(ur) + PPM_GETB(ll) + PPM_GETB(lr) / 4 );
  78.         break;
  79. #endif PPM
  80.  
  81. #ifdef PGM
  82.         case PGM_FORMAT:
  83.         case RPGM_FORMAT:
  84.         gul = (gray) PNM_GET1( ul );
  85.         gur = (gray) PNM_GET1( ur );
  86.         gll = (gray) PNM_GET1( ll );
  87.         glr = (gray) PNM_GET1( lr );
  88.         PNM_ASSIGN1( bgxel, ( ( gul + gur + gll + glr ) / 4 ) );
  89.         break;
  90. #endif PGM
  91.  
  92. #ifdef PBM
  93.         case PBM_FORMAT:
  94.         case RPBM_FORMAT:
  95.         pm_error(
  96.         "pnm_backgroundxel: four bits no two of which equal each other??",
  97.         0,0,0,0,0 );
  98. #endif PBM
  99.  
  100.         default:
  101.         pm_error( "can't happen", 0,0,0,0,0 );
  102.         }
  103.     }
  104.  
  105.     return bgxel;
  106.     }
  107.  
  108. xel
  109. pnm_whitexel( maxval, format )
  110. xelval maxval;
  111. int format;
  112.     {
  113.     xel x;
  114.  
  115.     switch ( format )
  116.     {
  117. #ifdef PPM
  118.     case PPM_FORMAT:
  119.     case RPPM_FORMAT:
  120.     PPM_ASSIGN( x, maxval, maxval, maxval );
  121.     break;
  122. #endif PPM
  123.  
  124. #ifdef PGM
  125.     case PGM_FORMAT:
  126.     case RPGM_FORMAT:
  127.     PNM_ASSIGN1( x, maxval );
  128.     break;
  129. #endif PGM
  130.  
  131. #ifdef PBM
  132.     case PBM_FORMAT:
  133.     case RPBM_FORMAT:
  134.     PNM_ASSIGN1( x, (xelval) PBM_WHITE );
  135.     break;
  136. #endif PBM
  137.  
  138.     default:
  139.     pm_error( "can't happen", 0,0,0,0,0 );
  140.     }
  141.  
  142.     return x;
  143.     }
  144.  
  145. xel
  146. pnm_blackxel( maxval, format )
  147. xelval maxval;
  148. int format;
  149.     {
  150.     xel x;
  151.  
  152.     switch ( format )
  153.     {
  154. #ifdef PPM
  155.     case PPM_FORMAT:
  156.     case RPPM_FORMAT:
  157.     PPM_ASSIGN( x, 0, 0, 0 );
  158.     break;
  159. #endif PPM
  160.  
  161. #ifdef PGM
  162.     case PGM_FORMAT:
  163.     case RPGM_FORMAT:
  164.     PNM_ASSIGN1( x, (xelval) 0 );
  165.     break;
  166. #endif PGM
  167.  
  168. #ifdef PBM
  169.     case PBM_FORMAT:
  170.     case RPBM_FORMAT:
  171.     PNM_ASSIGN1( x, (xelval) PBM_BLACK );
  172.     break;
  173. #endif PBM
  174.  
  175.     default:
  176.     pm_error( "can't happen", 0,0,0,0,0 );
  177.     }
  178.  
  179.     return x;
  180.     }
  181.  
  182. xel
  183. pnm_invertxel( x, maxval, format )
  184. xel x;
  185. xelval maxval;
  186. int format;
  187.     {
  188.     switch ( format )
  189.     {
  190. #ifdef PPM
  191.     case PPM_FORMAT:
  192.     case RPPM_FORMAT:
  193.     PPM_ASSIGN(
  194.         x, maxval - PPM_GETR( x ),
  195.         maxval - PPM_GETG( x ), maxval - PPM_GETB( x ) );
  196.     break;
  197. #endif PPM
  198.  
  199. #ifdef PGM
  200.     case PGM_FORMAT:
  201.     case RPGM_FORMAT:
  202.     PNM_ASSIGN1( x, (gray) maxval - (gray) PNM_GET1( x ) );
  203.     break;
  204. #endif PGM
  205.  
  206. #ifdef PBM
  207.     case PBM_FORMAT:
  208.     case RPBM_FORMAT:
  209.     PNM_ASSIGN1(
  210.         x, ( (bit) PNM_GET1( x ) == PBM_WHITE ) ? PBM_BLACK : PBM_WHITE );
  211.     break;
  212. #endif PBM
  213.  
  214.     default:
  215.     pm_error( "can't happen", 0,0,0,0,0 );
  216.     }
  217.     return x;
  218.     }
  219.  
  220. void
  221. pnm_promoteformat( xels, cols, rows, maxval, format, newmaxval, newformat )
  222. xel **xels;
  223. xelval maxval, newmaxval;
  224. int cols, rows, format, newformat;
  225.     {
  226.     int row;
  227.     register int col;
  228.     register xel *xP;
  229.  
  230. #ifdef PPM
  231.     if ( ( ( format == PPM_FORMAT || format == RPPM_FORMAT ) &&
  232.        ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ||
  233.          newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) ||
  234.      ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
  235.        ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
  236.     pm_error( "pnm_promoteformat: can't promote downwards!", 0,0,0,0,0 );
  237. #else PPM
  238. # ifdef PGM
  239.     if ( ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
  240.        ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
  241.     pm_error( "pnm_promoteformat: can't promote downwards!", 0,0,0,0,0 );
  242. # else PGM
  243. #  ifdef PBM
  244.     /* If only PBM is defined, we can just return. */
  245.     return;
  246. #  endif PBM
  247. # endif PGM
  248. #endif PPM
  249.  
  250. #ifdef PPM
  251.     if ( ( ( format == PPM_FORMAT || format == RPPM_FORMAT ) &&
  252.            ( newformat == PPM_FORMAT || newformat == RPPM_FORMAT ) ) ||
  253.          ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
  254.            ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ) ) ||
  255.          ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
  256.            ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
  257. #else PPM
  258. # ifdef PGM
  259.     if ( ( ( format == PGM_FORMAT || format == RPGM_FORMAT ) &&
  260.            ( newformat == PGM_FORMAT || newformat == RPGM_FORMAT ) ) ||
  261.          ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
  262.            ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
  263. # else PGM
  264. #  ifdef PBM
  265.     if ( ( ( format == PBM_FORMAT || format == RPBM_FORMAT ) &&
  266.            ( newformat == PBM_FORMAT || newformat == RPBM_FORMAT ) ) )
  267. #  endif PBM
  268. # endif PGM
  269. #endif PPM
  270.     {
  271. #ifdef PBM
  272.     if ( format == PBM_FORMAT || format == RPBM_FORMAT )
  273.         return;
  274. #endif PBM
  275.     if ( newmaxval < maxval )
  276.         pm_error(
  277.         "pnm_promoteformat: can't decrease maxval -- try using ppmcscale",
  278.         0,0,0,0,0 );
  279.     if ( newmaxval == maxval )
  280.         return;
  281.     /* Increase maxval. */
  282.     switch ( format )
  283.         {
  284. #ifdef PGM
  285.         case PGM_FORMAT:
  286.         case RPGM_FORMAT:
  287.         for ( row = 0; row < rows; row++ )
  288.         for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  289.             PNM_ASSIGN1(
  290.             *xP, (int) PNM_GET1(*xP) * newmaxval / maxval );
  291.         break;
  292. #endif PGM
  293.  
  294. #ifdef PPM
  295.         case PPM_FORMAT:
  296.         case RPPM_FORMAT:
  297.         for ( row = 0; row < rows; row++ )
  298.         for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  299.             PPM_CSCALE( *xP, *xP, maxval, newmaxval );
  300.         break;
  301. #endif PPM
  302.  
  303.         default:
  304.         pm_error( "shouldn't happen", 0,0,0,0,0 );
  305.         }
  306.     return;
  307.     }
  308.  
  309.     switch ( format )
  310.     {
  311. #ifdef PBM
  312.     case PBM_FORMAT:
  313.     case RPBM_FORMAT:
  314.     switch ( newformat )
  315.         {
  316. #ifdef PGM
  317.         case PGM_FORMAT:
  318.         case RPGM_FORMAT:
  319.         for ( row = 0; row < rows; row++ )
  320.         for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  321.             PNM_ASSIGN1(
  322.             *xP, ( PNM_GET1(*xP) == PBM_WHITE ) ? newmaxval : (xelval) 0 );
  323.         break;
  324. #endif PGM
  325.  
  326. #ifdef PPM
  327.         case PPM_FORMAT:
  328.         case RPPM_FORMAT:
  329.         for ( row = 0; row < rows; row++ )
  330.         for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  331.             if ( PNM_GET1(*xP) == PBM_WHITE )
  332.             PPM_ASSIGN( *xP, newmaxval, newmaxval, newmaxval );
  333.             else
  334.             PPM_ASSIGN( *xP, 0, 0, 0 );
  335.         break;
  336. #endif PPM
  337.  
  338.         default:
  339.         pm_error( "can't happen", 0,0,0,0,0 );
  340.         }
  341.     break;
  342. #endif PBM
  343.  
  344. #ifdef PGM
  345.     case PGM_FORMAT:
  346.     case RPGM_FORMAT:
  347.     switch ( newformat )
  348.         {
  349. #ifdef PPM
  350.         case PPM_FORMAT:
  351.         case RPPM_FORMAT:
  352.         if ( newmaxval < maxval )
  353.         pm_error(
  354.             "pnm_promoteformat: can't decrease maxval -- try using ppmcscale",
  355.             0,0,0,0,0 );
  356.         if ( newmaxval == maxval )
  357.         {
  358.         for ( row = 0; row < rows; row++ )
  359.             for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  360.             PPM_ASSIGN(
  361.                 *xP, PNM_GET1(*xP), PNM_GET1(*xP), PNM_GET1(*xP) );
  362.         }
  363.         else
  364.         { /* Increase maxval. */
  365.         for ( row = 0; row < rows; row++ )
  366.             for ( col = 0, xP = xels[row]; col < cols; col++, xP++ )
  367.             PPM_ASSIGN(
  368.                 *xP, (int) PNM_GET1(*xP) * newmaxval / maxval,
  369.                 (int) PNM_GET1(*xP) * newmaxval / maxval,
  370.                 (int) PNM_GET1(*xP) * newmaxval / maxval );
  371.         }
  372.         break;
  373. #endif PPM
  374.  
  375.         default:
  376.         pm_error( "can't happen", 0,0,0,0,0 );
  377.         }
  378.     break;
  379. #endif PGM
  380.  
  381.     default:
  382.     pm_error( "can't happen", 0,0,0,0,0 );
  383.     }
  384.     }
  385.