home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmpat.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  32KB  |  1,090 lines

  1. /* ppmpat.c - make a pixmap
  2. **
  3. ** Copyright (C) 1989, 1991 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 <math.h>
  14. #include "ppm.h"
  15. #include "ppmdraw.h"
  16. #ifndef M_PI
  17. #define M_PI    3.14159265358979323846
  18. #endif /*M_PI*/
  19.  
  20. static pixel random_color ARGS(( pixval maxval ));
  21. static pixel random_bright_color ARGS(( pixval maxval ));
  22. static pixel random_dark_color ARGS(( pixval maxval ));
  23. static pixel average_two_colors ARGS(( pixel p1, pixel p2 ));
  24. static void average_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  25. static void gingham2 ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  26. static void gingham3 ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  27. static void madras ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  28. static void tartan ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  29. static void poles ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  30. static void sq_measurecircle_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  31. static void sq_rainbowcircle_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  32. static void squig ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  33. static void sq_assign_colors ARGS(( int circlecount, pixval maxval, pixel* colors ));
  34. static pixel random_camo_color ARGS(( pixval maxval ));
  35. static pixel random_anticamo_color ARGS(( pixval maxval ));
  36. static float rnduni ARGS(( void ));
  37. static void camo ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int antiflag ));
  38. static void test ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  39.  
  40.  
  41. int
  42. main( argc, argv )
  43.     int argc;
  44.     char* argv[];
  45.     {
  46.     pixel** pixels;
  47.     int argn, pattern, cols, rows;
  48. #define PAT_NONE 0
  49. #define PAT_GINGHAM2 1
  50. #define PAT_GINGHAM3 2
  51. #define PAT_MADRAS 3
  52. #define PAT_TARTAN 4
  53. #define PAT_POLES 5
  54. #define PAT_SQUIG 6
  55. #define PAT_CAMO 7
  56. #define PAT_ANTICAMO 8
  57. #define PAT_TEST 9
  58.     char* usage = "-gingham|-g2|-gingham3|-g3|-madras|-tartan|-poles|-squig|-camo|-anticamo <width> <height>";
  59.  
  60.  
  61.     ppm_init( &argc, argv );
  62.  
  63.     argn = 1;
  64.     pattern = PAT_NONE;
  65.  
  66.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  67.     {
  68.     if ( pm_keymatch( argv[argn], "-gingham2", 9 ) ||
  69.          pm_keymatch( argv[argn], "-g2", 3 ) )
  70.         {
  71.         if ( pattern != PAT_NONE )
  72.         pm_error( "only one base pattern may be specified" );
  73.         pattern = PAT_GINGHAM2;
  74.         }
  75.     else if ( pm_keymatch( argv[argn], "-gingham3", 9 ) ||
  76.          pm_keymatch( argv[argn], "-g3", 3 ) )
  77.         {
  78.         if ( pattern != PAT_NONE )
  79.         pm_error( "only one base pattern may be specified" );
  80.         pattern = PAT_GINGHAM3;
  81.         }
  82.     else if ( pm_keymatch( argv[argn], "-madras", 2 ) )
  83.         {
  84.         if ( pattern != PAT_NONE )
  85.         pm_error( "only one base pattern may be specified" );
  86.         pattern = PAT_MADRAS;
  87.         }
  88.     else if ( pm_keymatch( argv[argn], "-tartan", 2 ) )
  89.         {
  90.         if ( pattern != PAT_NONE )
  91.         pm_error( "only one base pattern may be specified" );
  92.         pattern = PAT_TARTAN;
  93.         }
  94.     else if ( pm_keymatch( argv[argn], "-poles", 2 ) )
  95.         {
  96.         if ( pattern != PAT_NONE )
  97.         pm_error( "only one base pattern may be specified" );
  98.         pattern = PAT_POLES;
  99.         }
  100.     else if ( pm_keymatch( argv[argn], "-squig", 2 ) )
  101.         {
  102.         if ( pattern != PAT_NONE )
  103.         pm_error( "only one base pattern may be specified" );
  104.         pattern = PAT_SQUIG;
  105.         }
  106.     else if ( pm_keymatch( argv[argn], "-camo", 2 ) )
  107.         {
  108.         if ( pattern != PAT_NONE )
  109.         pm_error( "only one base pattern may be specified" );
  110.         pattern = PAT_CAMO;
  111.         }
  112.     else if ( pm_keymatch( argv[argn], "-anticamo", 2 ) )
  113.         {
  114.         if ( pattern != PAT_NONE )
  115.         pm_error( "only one base pattern may be specified" );
  116.         pattern = PAT_ANTICAMO;
  117.         }
  118.     else if ( pm_keymatch( argv[argn], "-test", 3 ) )
  119.         {
  120.         if ( pattern != PAT_NONE )
  121.         pm_error( "only one base pattern may be specified" );
  122.         pattern = PAT_TEST;
  123.         }
  124.     else
  125.         pm_usage( usage );
  126.     ++argn;
  127.     }
  128.     if ( pattern == PAT_NONE )
  129.     pm_error( "a base pattern must be specified" );
  130.  
  131.     if ( argn == argc )
  132.     pm_usage( usage);
  133.     if ( sscanf( argv[argn], "%d", &cols ) != 1 )
  134.     pm_usage( usage );
  135.     ++argn;
  136.     if ( argn == argc )
  137.     pm_usage( usage);
  138.     if ( sscanf( argv[argn], "%d", &rows ) != 1 )
  139.     pm_usage( usage );
  140.     ++argn;
  141.  
  142.     if ( argn != argc )
  143.     pm_usage( usage);
  144.  
  145.     srandom( (int) ( time( 0 ) ^ getpid( ) ) );
  146.     pixels = ppm_allocarray( cols, rows );
  147.  
  148.     switch ( pattern )
  149.     {
  150.     case PAT_GINGHAM2:
  151.     gingham2( pixels, cols, rows, PPM_MAXMAXVAL );
  152.     break;
  153.  
  154.     case PAT_GINGHAM3:
  155.     gingham3( pixels, cols, rows, PPM_MAXMAXVAL );
  156.     break;
  157.  
  158.     case PAT_MADRAS:
  159.     madras( pixels, cols, rows, PPM_MAXMAXVAL );
  160.     break;
  161.  
  162.     case PAT_TARTAN:
  163.     tartan( pixels, cols, rows, PPM_MAXMAXVAL );
  164.     break;
  165.  
  166.     case PAT_POLES:
  167.     poles( pixels, cols, rows, PPM_MAXMAXVAL );
  168.     break;
  169.  
  170.     case PAT_SQUIG:
  171.     squig( pixels, cols, rows, PPM_MAXMAXVAL );
  172.     break;
  173.  
  174.     case PAT_CAMO:
  175.     camo( pixels, cols, rows, PPM_MAXMAXVAL, 0 );
  176.     break;
  177.  
  178.     case PAT_ANTICAMO:
  179.     camo( pixels, cols, rows, PPM_MAXMAXVAL, 1 );
  180.     break;
  181.  
  182.     case PAT_TEST:
  183.     test( pixels, cols, rows, PPM_MAXMAXVAL );
  184.     break;
  185.  
  186.     default:
  187.     pm_error( "can't happen!" );
  188.     }
  189.  
  190.     /* All done, write it out. */
  191.     ppm_writeppm( stdout, pixels, cols, rows, PPM_MAXMAXVAL, 0 );
  192.     pm_close( stdout );
  193.  
  194.     exit( 0 );
  195.     }
  196.  
  197. #if __STDC__
  198. static pixel
  199. random_color( pixval maxval )
  200. #else /*__STDC__*/
  201. static pixel
  202. random_color( maxval )
  203.     pixval maxval;
  204. #endif /*__STDC__*/
  205.     {
  206.     pixel p;
  207.  
  208.     PPM_ASSIGN(
  209.     p, random() % ( maxval + 1 ), random() % ( maxval + 1 ),
  210.     random() % ( maxval + 1 ) );
  211.  
  212.     return p;
  213.     }
  214.  
  215. #define DARK_THRESH 0.25
  216.  
  217. #if __STDC__
  218. static pixel
  219. random_bright_color( pixval maxval )
  220. #else /*__STDC__*/
  221. static pixel
  222. random_bright_color( maxval )
  223.     pixval maxval;
  224. #endif /*__STDC__*/
  225.     {
  226.     pixel p;
  227.  
  228.     do
  229.     {
  230.     p = random_color( maxval );
  231.     }
  232.     while ( PPM_LUMIN( p ) <= maxval * DARK_THRESH );
  233.  
  234.     return p;
  235.     }
  236.  
  237. #if __STDC__
  238. static pixel
  239. random_dark_color( pixval maxval )
  240. #else /*__STDC__*/
  241. static pixel
  242. random_dark_color( maxval )
  243.     pixval maxval;
  244. #endif /*__STDC__*/
  245.     {
  246.     pixel p;
  247.  
  248.     do
  249.     {
  250.     p = random_color( maxval );
  251.     }
  252.     while ( PPM_LUMIN( p ) > maxval * DARK_THRESH );
  253.  
  254.     return p;
  255.     }
  256.  
  257. static pixel
  258. average_two_colors( p1, p2 )
  259. pixel p1, p2;
  260.     {
  261.     pixel p;
  262.  
  263.     PPM_ASSIGN(
  264.     p, ( (int) PPM_GETR(p1) + (int) PPM_GETR(p2) ) / 2,
  265.     ( (int) PPM_GETG(p1) + (int) PPM_GETG(p2) ) / 2,
  266.     ( (int) PPM_GETB(p1) + (int) PPM_GETB(p2) ) / 2 );
  267.  
  268.     return p;
  269.     }
  270.  
  271. #if __STDC__
  272. static void
  273. average_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  274. #else /*__STDC__*/
  275. static void
  276. average_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  277.     pixel** pixels;
  278.     int cols, rows, col, row;
  279.     pixval maxval;
  280.     char* clientdata;
  281. #endif /*__STDC__*/
  282.     {
  283.     if ( col >= 0 && col < cols && row >= 0 && row < rows )
  284.     pixels[row][col] =
  285.         average_two_colors( pixels[row][col], *( (pixel*) clientdata ) );
  286.     }
  287.  
  288. /* Gingham stuff. */
  289.  
  290. #if __STDC__
  291. static void
  292. gingham2( pixel** pixels, int cols, int rows, pixval maxval )
  293. #else /*__STDC__*/
  294. static void
  295. gingham2( pixels, cols, rows, maxval )
  296.     pixel** pixels;
  297.     int cols, rows;
  298.     pixval maxval;
  299. #endif /*__STDC__*/
  300.     {
  301.     int colso2, rowso2;
  302.     pixel backcolor, forecolor;
  303.  
  304.     colso2 = cols / 2;
  305.     rowso2 = rows / 2;
  306.     backcolor = random_dark_color( maxval );
  307.     forecolor = random_bright_color( maxval );
  308.  
  309.     /* Warp. */
  310.     ppmd_filledrectangle(
  311.     pixels, cols, rows, maxval, 0, 0, colso2, rows, PPMD_NULLDRAWPROC,
  312.     (char*) &backcolor );
  313.     ppmd_filledrectangle(
  314.     pixels, cols, rows, maxval, colso2, 0, cols - colso2, rows,
  315.     PPMD_NULLDRAWPROC, (char*) &forecolor );
  316.  
  317.     /* Woof. */
  318.     ppmd_filledrectangle(
  319.     pixels, cols, rows, maxval, 0, 0, cols, rowso2, average_drawproc,
  320.     (char*) &backcolor );
  321.     ppmd_filledrectangle(
  322.     pixels, cols, rows, maxval, 0, rowso2, cols, rows - rowso2,
  323.     average_drawproc, (char*) &forecolor );
  324.     }
  325.  
  326. #if __STDC__
  327. static void
  328. gingham3( pixel** pixels, int cols, int rows, pixval maxval )
  329. #else /*__STDC__*/
  330. static void
  331. gingham3( pixels, cols, rows, maxval )
  332.     pixel** pixels;
  333.     int cols, rows;
  334.     pixval maxval;
  335. #endif /*__STDC__*/
  336.     {
  337.     int colso4, rowso4;
  338.     pixel backcolor, fore1color, fore2color;
  339.  
  340.     colso4 = cols / 4;
  341.     rowso4 = rows / 4;
  342.     backcolor = random_dark_color( maxval );
  343.     fore1color = random_bright_color( maxval );
  344.     fore2color = random_bright_color( maxval );
  345.  
  346.     /* Warp. */
  347.     ppmd_filledrectangle(
  348.     pixels, cols, rows, maxval, 0, 0, colso4, rows, PPMD_NULLDRAWPROC,
  349.     (char*) &backcolor );
  350.     ppmd_filledrectangle(
  351.     pixels, cols, rows, maxval, colso4, 0, colso4, rows, PPMD_NULLDRAWPROC,
  352.     (char*) &fore1color );
  353.     ppmd_filledrectangle(
  354.     pixels, cols, rows, maxval, 2 * colso4, 0, colso4, rows,
  355.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  356.     ppmd_filledrectangle(
  357.     pixels, cols, rows, maxval, 3 * colso4, 0, cols - colso4, rows,
  358.     PPMD_NULLDRAWPROC, (char*) &fore1color );
  359.  
  360.     /* Woof. */
  361.     ppmd_filledrectangle(
  362.     pixels, cols, rows, maxval, 0, 0, cols, rowso4, average_drawproc,
  363.     (char*) &backcolor );
  364.     ppmd_filledrectangle(
  365.     pixels, cols, rows, maxval, 0, rowso4, cols, rowso4, average_drawproc,
  366.     (char*) &fore1color );
  367.     ppmd_filledrectangle(
  368.     pixels, cols, rows, maxval, 0, 2 * rowso4, cols, rowso4,
  369.     average_drawproc, (char*) &fore2color );
  370.     ppmd_filledrectangle(
  371.     pixels, cols, rows, maxval, 0, 3 * rowso4, cols, rows - rowso4,
  372.     average_drawproc, (char*) &fore1color );
  373.     }
  374.  
  375. #if __STDC__
  376. static void
  377. madras( pixel** pixels, int cols, int rows, pixval maxval )
  378. #else /*__STDC__*/
  379. static void
  380. madras( pixels, cols, rows, maxval )
  381.     pixel** pixels;
  382.     int cols, rows;
  383.     pixval maxval;
  384. #endif /*__STDC__*/
  385.     {
  386.     int cols2, rows2, cols3, rows3, cols12, rows12, cols6a, rows6a, cols6b,
  387.     rows6b;
  388.     pixel backcolor, fore1color, fore2color;
  389.  
  390.     cols2 = cols * 2 / 44;
  391.     rows2 = rows * 2 / 44;
  392.     cols3 = cols * 3 / 44;
  393.     rows3 = rows * 3 / 44;
  394.     cols12 = cols - 10 * cols2 - 4 * cols3;
  395.     rows12 = rows - 10 * rows2 - 4 * rows3;
  396.     cols6a = cols12 / 2;
  397.     rows6a = rows12 / 2;
  398.     cols6b = cols12 - cols6a;
  399.     rows6b = rows12 - rows6a;
  400.     backcolor = random_dark_color( maxval );
  401.     fore1color = random_bright_color( maxval );
  402.     fore2color = random_bright_color( maxval );
  403.  
  404.     /* Warp. */
  405.     ppmd_filledrectangle(
  406.     pixels, cols, rows, maxval, 0, 0, cols2, rows, PPMD_NULLDRAWPROC,
  407.     (char*) &backcolor );
  408.     ppmd_filledrectangle(
  409.     pixels, cols, rows, maxval, cols2, 0, cols3, rows, PPMD_NULLDRAWPROC,
  410.     (char*) &fore1color );
  411.     ppmd_filledrectangle(
  412.     pixels, cols, rows, maxval, cols2 + cols3, 0, cols2, rows,
  413.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  414.     ppmd_filledrectangle(
  415.     pixels, cols, rows, maxval, 2 * cols2 + cols3, 0, cols2, rows,
  416.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  417.     ppmd_filledrectangle(
  418.     pixels, cols, rows, maxval, 3 * cols2 + cols3, 0, cols2, rows,
  419.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  420.     ppmd_filledrectangle(
  421.     pixels, cols, rows, maxval, 4 * cols2 + cols3, 0, cols6a, rows,
  422.     PPMD_NULLDRAWPROC, (char*) &fore1color );
  423.     ppmd_filledrectangle(
  424.     pixels, cols, rows, maxval, 4 * cols2 + cols3 + cols6a, 0, cols2, rows,
  425.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  426.     ppmd_filledrectangle(
  427.     pixels, cols, rows, maxval, 5 * cols2 + cols3 + cols6a, 0, cols3, rows,
  428.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  429.     ppmd_filledrectangle(
  430.     pixels, cols, rows, maxval, 5 * cols2 + 2 * cols3 + cols6a, 0, cols2,
  431.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  432.     ppmd_filledrectangle(
  433.     pixels, cols, rows, maxval, 6 * cols2 + 2 * cols3 + cols6a, 0, cols3,
  434.     rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  435.     ppmd_filledrectangle(
  436.     pixels, cols, rows, maxval, 6 * cols2 + 3 * cols3 + cols6a, 0, cols2,
  437.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  438.     ppmd_filledrectangle(
  439.     pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a, 0, cols6b,
  440.     rows, PPMD_NULLDRAWPROC, (char*) &fore1color );
  441.     ppmd_filledrectangle(
  442.     pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  443.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  444.     ppmd_filledrectangle(
  445.     pixels, cols, rows, maxval, 8 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  446.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  447.     ppmd_filledrectangle(
  448.     pixels, cols, rows, maxval, 9 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  449.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  450.     ppmd_filledrectangle(
  451.     pixels, cols, rows, maxval, 10 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  452.     cols3, rows, PPMD_NULLDRAWPROC, (char*) &fore1color );
  453.  
  454.     /* Woof. */
  455.     ppmd_filledrectangle(
  456.     pixels, cols, rows, maxval, 0, 0, cols, rows2, average_drawproc,
  457.     (char*) &backcolor );
  458.     ppmd_filledrectangle(
  459.     pixels, cols, rows, maxval, 0, rows2, cols, rows3, average_drawproc,
  460.     (char*) &fore2color );
  461.     ppmd_filledrectangle(
  462.     pixels, cols, rows, maxval, 0, rows2 + rows3, cols, rows2,
  463.     average_drawproc, (char*) &backcolor );
  464.     ppmd_filledrectangle(
  465.     pixels, cols, rows, maxval, 0, 2 * rows2 + rows3, cols, rows2,
  466.     average_drawproc, (char*) &fore1color );
  467.     ppmd_filledrectangle(
  468.     pixels, cols, rows, maxval, 0, 3 * rows2 + rows3, cols, rows2,
  469.     average_drawproc, (char*) &backcolor );
  470.     ppmd_filledrectangle(
  471.     pixels, cols, rows, maxval, 0, 4 * rows2 + rows3, cols, rows6a,
  472.     average_drawproc, (char*) &fore2color );
  473.     ppmd_filledrectangle(
  474.     pixels, cols, rows, maxval, 0, 4 * rows2 + rows3 + rows6a, cols, rows2,
  475.     average_drawproc, (char*) &backcolor );
  476.     ppmd_filledrectangle(
  477.     pixels, cols, rows, maxval, 0, 5 * rows2 + rows3 + rows6a, cols, rows3,
  478.     average_drawproc, (char*) &fore1color );
  479.     ppmd_filledrectangle(
  480.     pixels, cols, rows, maxval, 0, 5 * rows2 + 2 * rows3 + rows6a, cols,
  481.     rows2, average_drawproc, (char*) &backcolor );
  482.     ppmd_filledrectangle(
  483.     pixels, cols, rows, maxval, 0, 6 * rows2 + 2 * rows3 + rows6a, cols,
  484.     rows3, average_drawproc, (char*) &fore1color );
  485.     ppmd_filledrectangle(
  486.     pixels, cols, rows, maxval, 0, 6 * rows2 + 3 * rows3 + rows6a, cols,
  487.     rows2, average_drawproc, (char*) &backcolor );
  488.     ppmd_filledrectangle(
  489.     pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a, cols,
  490.     rows6b, average_drawproc, (char*) &fore2color );
  491.     ppmd_filledrectangle(
  492.     pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a + rows6b,
  493.     cols, rows2, average_drawproc, (char*) &backcolor );
  494.     ppmd_filledrectangle(
  495.     pixels, cols, rows, maxval, 0, 8 * rows2 + 3 * rows3 + rows6a + rows6b,
  496.     cols, rows2, average_drawproc, (char*) &fore1color );
  497.     ppmd_filledrectangle(
  498.     pixels, cols, rows, maxval, 0, 9 * rows2 + 3 * rows3 + rows6a + rows6b,
  499.     cols, rows2, average_drawproc, (char*) &backcolor );
  500.     ppmd_filledrectangle(
  501.     pixels, cols, rows, maxval, 0, 10 * rows2 + 3 * rows3 + rows6a + rows6b,
  502.     cols, rows3, average_drawproc, (char*) &fore2color );
  503.     }
  504.  
  505. #if __STDC__
  506. static void
  507. tartan( pixel** pixels, int cols, int rows, pixval maxval )
  508. #else /*__STDC__*/
  509. static void
  510. tartan( pixels, cols, rows, maxval )
  511.     pixel** pixels;
  512.     int cols, rows;
  513.     pixval maxval;
  514. #endif /*__STDC__*/
  515.     {
  516.     int cols1, rows1, cols3, rows3, cols10, rows10, cols5a, rows5a, cols5b,
  517.     rows5b;
  518.     pixel backcolor, fore1color, fore2color;
  519.  
  520.     cols1 = cols / 22;
  521.     rows1 = rows / 22;
  522.     cols3 = cols * 3 / 22;
  523.     rows3 = rows * 3 / 22;
  524.     cols10 = cols - 3 * cols1 - 3 * cols3;
  525.     rows10 = rows - 3 * rows1 - 3 * rows3;
  526.     cols5a = cols10 / 2;
  527.     rows5a = rows10 / 2;
  528.     cols5b = cols10 - cols5a;
  529.     rows5b = rows10 - rows5a;
  530.     backcolor = random_dark_color( maxval );
  531.     fore1color = random_bright_color( maxval );
  532.     fore2color = random_bright_color( maxval );
  533.  
  534.     /* Warp. */
  535.     ppmd_filledrectangle(
  536.     pixels, cols, rows, maxval, 0, 0, cols5a, rows, PPMD_NULLDRAWPROC,
  537.     (char*) &backcolor );
  538.     ppmd_filledrectangle(
  539.     pixels, cols, rows, maxval, cols5a, 0, cols1, rows, PPMD_NULLDRAWPROC,
  540.     (char*) &fore1color );
  541.     ppmd_filledrectangle(
  542.     pixels, cols, rows, maxval, cols5a + cols1, 0, cols5b, rows,
  543.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  544.     ppmd_filledrectangle(
  545.     pixels, cols, rows, maxval, cols10 + cols1, 0, cols3, rows,
  546.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  547.     ppmd_filledrectangle(
  548.     pixels, cols, rows, maxval, cols10 + cols1 + cols3, 0, cols1, rows,
  549.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  550.     ppmd_filledrectangle(
  551.     pixels, cols, rows, maxval, cols10 + 2 * cols1 + cols3, 0, cols3, rows,
  552.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  553.     ppmd_filledrectangle(
  554.     pixels, cols, rows, maxval, cols10 + 2 * cols1 + 2 * cols3, 0, cols1,
  555.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  556.     ppmd_filledrectangle(
  557.     pixels, cols, rows, maxval, cols10 + 3 * cols1 + 2 * cols3, 0, cols3,
  558.     rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  559.  
  560.     /* Woof. */
  561.     ppmd_filledrectangle(
  562.     pixels, cols, rows, maxval, 0, 0, cols, rows5a, average_drawproc,
  563.     (char*) &backcolor );
  564.     ppmd_filledrectangle(
  565.     pixels, cols, rows, maxval, 0, rows5a, cols, rows1, average_drawproc,
  566.     (char*) &fore1color );
  567.     ppmd_filledrectangle(
  568.     pixels, cols, rows, maxval, 0, rows5a + rows1, cols, rows5b,
  569.     average_drawproc, (char*) &backcolor );
  570.     ppmd_filledrectangle(
  571.     pixels, cols, rows, maxval, 0, rows10 + rows1, cols, rows3,
  572.     average_drawproc, (char*) &fore2color );
  573.     ppmd_filledrectangle(
  574.     pixels, cols, rows, maxval, 0, rows10 + rows1 + rows3, cols, rows1,
  575.     average_drawproc, (char*) &backcolor );
  576.     ppmd_filledrectangle(
  577.     pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + rows3, cols, rows3,
  578.     average_drawproc, (char*) &fore2color );
  579.     ppmd_filledrectangle(
  580.     pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + 2 * rows3, cols,
  581.     rows1, average_drawproc, (char*) &backcolor );
  582.     ppmd_filledrectangle(
  583.     pixels, cols, rows, maxval, 0, rows10 + 3 * rows1 + 2 * rows3, cols,
  584.     rows3, average_drawproc, (char*) &fore2color );
  585.     }
  586.  
  587. /* Poles stuff. */
  588.  
  589. #define MAXPOLES 500
  590.  
  591. #if __STDC__
  592. static void
  593. poles( pixel** pixels, int cols, int rows, pixval maxval )
  594. #else /*__STDC__*/
  595. static void
  596. poles( pixels, cols, rows, maxval )
  597.     pixel** pixels;
  598.     int cols, rows;
  599.     pixval maxval;
  600. #endif /*__STDC__*/
  601.     {
  602.     int poles, i, xs[MAXPOLES], ys[MAXPOLES], col, row;
  603.     pixel colors[MAXPOLES];
  604.  
  605.     poles = cols * rows / 30000;
  606.  
  607.     /* Place and color poles randomly. */
  608.     for ( i = 0; i < poles; ++i )
  609.     {
  610.     xs[i] = random() % cols;
  611.     ys[i] = random() % rows;
  612.     colors[i] = random_bright_color( maxval );
  613.     }
  614.  
  615.     /* Now interpolate points. */
  616.     for ( row = 0; row < rows; ++row )
  617.     for ( col = 0; col < cols; ++col )
  618.         {
  619.         register long dist1, dist2, newdist, r, g, b;
  620.         pixel color1, color2;
  621.  
  622.         /* Find two closest poles. */
  623.         dist1 = dist2 = 2000000000;
  624.         for ( i = 0; i < poles; ++i )
  625.         {
  626.         newdist = ( col - xs[i] ) * ( col - xs[i] ) +
  627.               ( row - ys[i] ) * ( row - ys[i] );
  628.         if ( newdist < dist1 )
  629.             {
  630.             dist1 = newdist;
  631.             color1 = colors[i];
  632.             }
  633.         else if ( newdist < dist2 )
  634.             {
  635.             dist2 = newdist;
  636.             color2 = colors[i];
  637.             }
  638.         }
  639.  
  640.         /* And assign interpolated color. */
  641.         newdist = dist1 + dist2;
  642.         r = PPM_GETR(color1)*dist2/newdist + PPM_GETR(color2)*dist1/newdist;
  643.         g = PPM_GETG(color1)*dist2/newdist + PPM_GETG(color2)*dist1/newdist;
  644.         b = PPM_GETB(color1)*dist2/newdist + PPM_GETB(color2)*dist1/newdist;
  645.         PPM_ASSIGN( pixels[row][col], r, g, b );
  646.         }
  647.     }
  648.  
  649. /* Squig stuff. */
  650.  
  651. #define SQUIGS 5
  652. #define SQ_POINTS 7
  653. #define SQ_MAXCIRCLE_POINTS 5000
  654.  
  655. static int sq_radius, sq_circlecount;
  656. static pixel sq_colors[SQ_MAXCIRCLE_POINTS];
  657. static int sq_xoffs[SQ_MAXCIRCLE_POINTS], sq_yoffs[SQ_MAXCIRCLE_POINTS];
  658.  
  659. #if __STDC__
  660. static void
  661. sq_measurecircle_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  662. #else /*__STDC__*/
  663. static void
  664. sq_measurecircle_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  665.     pixel** pixels;
  666.     int cols, rows, col, row;
  667.     pixval maxval;
  668.     char* clientdata;
  669. #endif /*__STDC__*/
  670.     {
  671.     sq_xoffs[sq_circlecount] = col;
  672.     sq_yoffs[sq_circlecount] = row;
  673.     ++sq_circlecount;
  674.     }
  675.  
  676. #if __STDC__
  677. static void
  678. sq_rainbowcircle_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  679. #else /*__STDC__*/
  680. static void
  681. sq_rainbowcircle_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  682.     pixel** pixels;
  683.     int cols, rows, col, row;
  684.     pixval maxval;
  685.     char* clientdata;
  686. #endif /*__STDC__*/
  687.     {
  688.     int i;
  689.  
  690.     for ( i = 0; i < sq_circlecount; ++i )
  691.     ppmd_point_drawproc(
  692.         pixels, cols, rows, maxval, col + sq_xoffs[i], row + sq_yoffs[i],
  693.         (char*) &(sq_colors[i]) );
  694.     }
  695.  
  696. #if __STDC__
  697. static void
  698. squig( pixel** pixels, int cols, int rows, pixval maxval )
  699. #else /*__STDC__*/
  700. static void
  701. squig( pixels, cols, rows, maxval )
  702.     pixel** pixels;
  703.     int cols, rows;
  704.     pixval maxval;
  705. #endif /*__STDC__*/
  706.     {
  707.     pixel color;
  708.     int i, j, xc[SQ_POINTS], yc[SQ_POINTS], x0, y0, x1, y1, x2, y2, x3, y3;
  709.  
  710.     /* Clear image to black. */
  711.     PPM_ASSIGN( color, 0, 0, 0 );
  712.     ppmd_filledrectangle(
  713.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  714.     (char*) &color );
  715.  
  716.     /* Draw the squigs. */
  717.     (void) ppmd_setlinetype( PPMD_LINETYPE_NODIAGS );
  718.     (void) ppmd_setlineclip( 0 );
  719.     for ( i = SQUIGS; i > 0; --i )
  720.     {
  721.     /* Measure circle. */
  722.     sq_radius = ( cols + rows ) / 2 / ( 25 + i * 2 );
  723.     sq_circlecount = 0;
  724.     ppmd_circle(
  725.         pixels, cols, rows, maxval, 0, 0, sq_radius,
  726.         sq_measurecircle_drawproc, 0 );
  727.     sq_assign_colors( sq_circlecount, maxval, sq_colors );
  728.  
  729.     /* Choose wrap-around point. */
  730.     switch ( random() % 4 )
  731.         {
  732.         case 0:
  733.         x1 = random() % cols;
  734.         y1 = 0;
  735.         if ( x1 < cols / 2 )
  736.         xc[0] = random() % ( x1 * 2 );
  737.         else
  738.         xc[0] = cols - 1 - random() % ( ( cols - x1 ) * 2 );
  739.         yc[0] = random() % rows;
  740.         x2 = x1;
  741.         y2 = rows - 1;
  742.         xc[SQ_POINTS - 1] = 2 * x2 - xc[0];
  743.         yc[SQ_POINTS - 1] = y2 - yc[0];
  744.         x0 = xc[SQ_POINTS - 1];
  745.         y0 = yc[SQ_POINTS - 1] - rows;
  746.         x3 = xc[0];
  747.         y3 = yc[0] + rows;
  748.         break;
  749.  
  750.         case 1:
  751.         x2 = random() % cols;
  752.         y2 = 0;
  753.         if ( x2 < cols / 2 )
  754.         xc[SQ_POINTS - 1] = random() % ( x2 * 2 );
  755.         else
  756.         xc[SQ_POINTS - 1] = cols - 1 - random() % ( ( cols - x2 ) * 2 );
  757.         yc[SQ_POINTS - 1] = random() % rows;
  758.         x1 = x2;
  759.         y1 = rows - 1;
  760.         xc[0] = 2 * x1 - xc[SQ_POINTS - 1];
  761.         yc[0] = y1 - yc[SQ_POINTS - 1];
  762.         x0 = xc[SQ_POINTS - 1];
  763.         y0 = yc[SQ_POINTS - 1] + rows;
  764.         x3 = xc[0];
  765.         y3 = yc[0] - rows;
  766.         break;
  767.  
  768.         case 2:
  769.         x1 = 0;
  770.         y1 = random() % rows;
  771.         xc[0] = random() % cols;
  772.         if ( y1 < rows / 2 )
  773.         yc[0] = random() % ( y1 * 2 );
  774.         else
  775.         yc[0] = rows - 1 - random() % ( ( rows - y1 ) * 2 );
  776.         x2 = cols - 1;
  777.         y2 = y1;
  778.         xc[SQ_POINTS - 1] = x2 - xc[0];
  779.         yc[SQ_POINTS - 1] = 2 * y2 - yc[0];
  780.         x0 = xc[SQ_POINTS - 1] - cols;
  781.         y0 = yc[SQ_POINTS - 1];
  782.         x3 = xc[0] + cols;
  783.         y3 = yc[0];
  784.         break;
  785.  
  786.         case 3:
  787.         x2 = 0;
  788.         y2 = random() % rows;
  789.         xc[SQ_POINTS - 1] = random() % cols;
  790.         if ( y2 < rows / 2 )
  791.         yc[SQ_POINTS - 1] = random() % ( y2 * 2 );
  792.         else
  793.         yc[SQ_POINTS - 1] = rows - 1 - random() % ( ( rows - y2 ) * 2 );
  794.         x1 = cols - 1;
  795.         y1 = y2;
  796.         xc[0] = x1 - xc[SQ_POINTS - 1];
  797.         yc[0] = 2 * y1 - yc[SQ_POINTS - 1];
  798.         x0 = xc[SQ_POINTS - 1] + cols;
  799.         y0 = yc[SQ_POINTS - 1];
  800.         x3 = xc[0] - cols;
  801.         y3 = yc[0];
  802.         break;
  803.         }
  804.  
  805.     for ( j = 1; j < SQ_POINTS - 1; ++j )
  806.         {
  807.         xc[j] = ( random() % ( cols - 2 * sq_radius ) ) + sq_radius;
  808.         yc[j] = ( random() % ( rows - 2 * sq_radius ) ) + sq_radius;
  809.         }
  810.  
  811.     ppmd_line(
  812.         pixels, cols, rows, maxval, x0, y0, x1, y1,
  813.         sq_rainbowcircle_drawproc, 0 );
  814.     ppmd_polyspline(
  815.         pixels, cols, rows, maxval, x1, y1, SQ_POINTS, xc, yc, x2, y2,
  816.         sq_rainbowcircle_drawproc, 0 );
  817.     ppmd_line(
  818.         pixels, cols, rows, maxval, x2, y2, x3, y3,
  819.         sq_rainbowcircle_drawproc, 0 );
  820.     }
  821.     }
  822.  
  823. #if __STDC__
  824. static void
  825. sq_assign_colors( int circlecount, pixval maxval, pixel* colors )
  826. #else /*__STDC__*/
  827. static void
  828. sq_assign_colors( circlecount, maxval, colors )
  829.     int circlecount;
  830.     pixval maxval;
  831.     pixel* colors;
  832. #endif /*__STDC__*/
  833.     {
  834.     pixel rc1, rc2, rc3;
  835.     float cco3;
  836.     int i;
  837.  
  838.     rc1 = random_bright_color( maxval );
  839.     rc2 = random_bright_color( maxval );
  840.     rc3 = random_bright_color( maxval );
  841.     cco3 = ( circlecount - 1 ) / 3.0;
  842.  
  843.     for ( i = 0; i < circlecount ; ++i )
  844.     {
  845.     if ( i < cco3 )
  846.         PPM_ASSIGN(
  847.         colors[i],
  848.         (float) PPM_GETR(rc1) +
  849.             ( (float) PPM_GETR(rc2) - (float) PPM_GETR(rc1) ) *
  850.             (float) i / cco3,
  851.         (float) PPM_GETG(rc1) +
  852.             ( (float) PPM_GETG(rc2) - (float) PPM_GETG(rc1) ) *
  853.             (float) i / cco3,
  854.         (float) PPM_GETB(rc1) +
  855.             ( (float) PPM_GETB(rc2) - (float) PPM_GETB(rc1) ) *
  856.             (float) i / cco3 );
  857.     else if ( i < 2.0 * cco3 )
  858.         PPM_ASSIGN(
  859.         colors[i],
  860.         (float) PPM_GETR(rc2) +
  861.             ( (float) PPM_GETR(rc3) - (float) PPM_GETR(rc2) ) *
  862.             ( (float) i / cco3 - 1.0 ),
  863.         (float) PPM_GETG(rc2) +
  864.             ( (float) PPM_GETG(rc3) - (float) PPM_GETG(rc2) ) *
  865.             ( (float) i / cco3 - 1.0 ),
  866.         (float) PPM_GETB(rc2) +
  867.             ( (float) PPM_GETB(rc3) - (float) PPM_GETB(rc2) ) *
  868.             ( (float) i / cco3 - 1.0 ) );
  869.     else
  870.         PPM_ASSIGN(
  871.         colors[i],
  872.         (float) PPM_GETR(rc3) +
  873.             ( (float) PPM_GETR(rc1) - (float) PPM_GETR(rc3) ) *
  874.             ( (float) i / cco3 - 2.0 ),
  875.         (float) PPM_GETG(rc3) +
  876.             ( (float) PPM_GETG(rc1) - (float) PPM_GETG(rc3) ) *
  877.             ( (float) i / cco3 - 2.0 ),
  878.         (float) PPM_GETB(rc3) +
  879.             ( (float) PPM_GETB(rc1) - (float) PPM_GETB(rc3) ) *
  880.             ( (float) i / cco3 - 2.0 ) );
  881.     }
  882.     }
  883.  
  884. /* Camouflage stuff. */
  885.  
  886. #if __STDC__
  887. static pixel
  888. random_camo_color( pixval maxval )
  889. #else /*__STDC__*/
  890. static pixel
  891. random_camo_color( maxval )
  892.     pixval maxval;
  893. #endif /*__STDC__*/
  894.     {
  895.     int v1, v2, v3;
  896.     pixel p;
  897.  
  898.     v1 = ( (int) maxval + 1 ) / 8;
  899.     v2 = ( (int) maxval + 1 ) / 4;
  900.     v3 = ( (int) maxval + 1 ) / 2;
  901.  
  902.     switch ( random() % 10 )
  903.     {
  904.     case 0:    case 1: case 2: /* light brown */
  905.     PPM_ASSIGN(
  906.         p, random() % v3 + v3, random() % v3 + v2, random() % v3 + v2 );
  907.     break;
  908.  
  909.     case 3:    case 4: case 5: /* dark green */
  910.     PPM_ASSIGN( p, random() % v2, random() % v2 + 3 * v1, random() % v2 );
  911.     break;
  912.  
  913.     case 6:    case 7: /* brown */
  914.     PPM_ASSIGN( p, random() % v2 + v2, random() % v2, random() % v2 );
  915.     break;
  916.  
  917.     case 8:    case 9: /* dark brown */
  918.     PPM_ASSIGN( p, random() % v1 + v1, random() % v1, random() % v1 );
  919.     break;
  920.     }
  921.  
  922.     return p;
  923.     }
  924.  
  925. #if __STDC__
  926. static pixel
  927. random_anticamo_color( pixval maxval )
  928. #else /*__STDC__*/
  929. static pixel
  930. random_anticamo_color( maxval )
  931.     pixval maxval;
  932. #endif /*__STDC__*/
  933.     {
  934.     int v1, v2, v3;
  935.     pixel p;
  936.  
  937.     v1 = ( (int) maxval + 1 ) / 4;
  938.     v2 = ( (int) maxval + 1 ) / 2;
  939.     v3 = 3 * v1;
  940.  
  941.     switch ( random() % 15 )
  942.     {
  943.     case 0: case 1:
  944.     PPM_ASSIGN( p, random() % v1 + v3, random() % v2, random() % v2 );
  945.     break;
  946.  
  947.     case 2: case 3:
  948.     PPM_ASSIGN( p, random() % v2, random() % v1 + v3, random() % v2 );
  949.     break;
  950.  
  951.     case 4: case 5:
  952.     PPM_ASSIGN( p, random() % v2, random() % v2, random() % v1 + v3 );
  953.     break;
  954.  
  955.     case 6: case 7: case 8:
  956.     PPM_ASSIGN( p, random() % v2, random() % v1 + v3, random() % v1 + v3 );
  957.     break;
  958.  
  959.     case 9: case 10: case 11:
  960.     PPM_ASSIGN( p, random() % v1 + v3, random() % v2, random() % v1 + v3 );
  961.     break;
  962.  
  963.     case 12: case 13: case 14:
  964.     PPM_ASSIGN( p, random() % v1 + v3, random() % v1 + v3, random() % v2 );
  965.     break;
  966.  
  967.     }
  968.  
  969.     return p;
  970.     }
  971.  
  972. static float
  973. rnduni( )
  974.     {
  975.     return random() % 32767 / 32767.0;
  976.     }
  977.  
  978. #define BLOBRAD 50
  979.  
  980. #define MIN_POINTS 7
  981. #define MAX_POINTS 13
  982.  
  983. #define MIN_ELLIPSE_FACTOR 0.5
  984. #define MAX_ELLIPSE_FACTOR 2.0
  985.  
  986. #define MIN_POINT_FACTOR 0.5
  987. #define MAX_POINT_FACTOR 2.0
  988.  
  989. #if __STDC__
  990. static void
  991. camo( pixel** pixels, int cols, int rows, pixval maxval, int antiflag )
  992. #else /*__STDC__*/
  993. static void
  994. camo( pixels, cols, rows, maxval, antiflag )
  995.     pixel** pixels;
  996.     int cols, rows, antiflag;
  997.     pixval maxval;
  998. #endif /*__STDC__*/
  999.     {
  1000.     pixel color;
  1001.     int n, i, cx, cy;
  1002.     char* fh;
  1003.  
  1004.     /* Clear background. */
  1005.     if ( antiflag )
  1006.     color = random_anticamo_color( maxval );
  1007.     else
  1008.     color = random_camo_color( maxval );
  1009.     ppmd_filledrectangle(
  1010.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  1011.     (char*) &color );
  1012.  
  1013.     n = ( rows * cols ) / ( BLOBRAD * BLOBRAD ) * 5;
  1014.     for ( i = 0; i < n; ++i )
  1015.     {
  1016.     int points, p, xs[MAX_POINTS], ys[MAX_POINTS], x0, y0;
  1017.     float a, b, c, theta, tang, tx, ty;
  1018.  
  1019.     cx = random() % cols;
  1020.     cy = random() % rows;
  1021.  
  1022.     points = random() % ( MAX_POINTS - MIN_POINTS + 1 ) + MIN_POINTS;
  1023.     a = rnduni() * ( MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR ) +
  1024.         MIN_ELLIPSE_FACTOR;
  1025.     b = rnduni() * ( MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR ) +
  1026.         MIN_ELLIPSE_FACTOR;
  1027.     theta = rnduni() * 2.0 * M_PI;
  1028.     for ( p = 0; p < points; ++p )
  1029.         {
  1030.         tx = a * sin( p * 2.0 * M_PI / points );
  1031.         ty = b * cos( p * 2.0 * M_PI / points );
  1032.         tang = atan2( ty, tx ) + theta;
  1033.         c = rnduni() * ( MAX_POINT_FACTOR - MIN_POINT_FACTOR ) +
  1034.         MIN_POINT_FACTOR;
  1035.         xs[p] = cx + BLOBRAD * c * sin( tang );
  1036.         ys[p] = cy + BLOBRAD * c * cos( tang );
  1037.         }
  1038.     x0 = ( xs[0] + xs[points - 1] ) / 2;
  1039.     y0 = ( ys[0] + ys[points - 1] ) / 2;
  1040.  
  1041.     fh = ppmd_fill_init();
  1042.  
  1043.     ppmd_polyspline(
  1044.         pixels, cols, rows, maxval, x0, y0, points, xs, ys, x0, y0,
  1045.         ppmd_fill_drawproc, fh );
  1046.  
  1047.     if ( antiflag )
  1048.         color = random_anticamo_color( maxval );
  1049.     else
  1050.         color = random_camo_color( maxval );
  1051.     ppmd_fill( pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, (char*) &color );
  1052.     }
  1053.     }
  1054.  
  1055. /* Test pattern.  Just a place to put ppmdraw exercises. */
  1056.  
  1057. #if __STDC__
  1058. static void
  1059. test( pixel** pixels, int cols, int rows, pixval maxval )
  1060. #else /*__STDC__*/
  1061. static void
  1062. test( pixels, cols, rows, maxval )
  1063.     pixel** pixels;
  1064.     int cols, rows;
  1065.     pixval maxval;
  1066. #endif /*__STDC__*/
  1067.     {
  1068.     pixel color;
  1069.     char* fh;
  1070.  
  1071.     /* Clear image to black. */
  1072.     PPM_ASSIGN( color, 0, 0, 0 );
  1073.     ppmd_filledrectangle(
  1074.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  1075.     (char*) &color );
  1076.  
  1077.     fh = ppmd_fill_init();
  1078.  
  1079.     ppmd_line( pixels, cols, rows, maxval, cols/8, rows/8, cols/2, rows/4, ppmd_fill_drawproc, fh );
  1080.     ppmd_line( pixels, cols, rows, maxval, cols/2, rows/4, cols-cols/8, rows/8, ppmd_fill_drawproc, fh );
  1081.     ppmd_line( pixels, cols, rows, maxval, cols-cols/8, rows/8, cols/2, rows/2, ppmd_fill_drawproc, fh );
  1082.     ppmd_spline3( pixels, cols, rows, maxval, cols/2, rows/2, cols/2-cols/16, rows/2-rows/10, cols/2-cols/8, rows/2, ppmd_fill_drawproc, fh );
  1083.     ppmd_spline3( pixels, cols, rows, maxval, cols/2-cols/8, rows/2, cols/4+cols/16, rows/2+rows/10, cols/4, rows/2, ppmd_fill_drawproc, fh );
  1084.     ppmd_line( pixels, cols, rows, maxval, cols/4, rows/2, cols/8, rows/2, ppmd_fill_drawproc, fh );
  1085.     ppmd_line( pixels, cols, rows, maxval, cols/8, rows/2, cols/8, rows/8, ppmd_fill_drawproc, fh );
  1086.  
  1087.     PPM_ASSIGN( color, maxval, maxval, maxval );
  1088.     ppmd_fill( pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, (char*) &color );
  1089.     }
  1090.