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

  1. /* ppmtorast.c - read a portable pixmap and produce a Sun rasterfile
  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.  
  17. /* This program compiles only on Suns. */
  18. #include <pixrect/pixrect_hs.h>
  19.  
  20. #define MAXCOLORS 256
  21.  
  22. main( argc, argv )
  23. int argc;
  24. char *argv[];
  25.     {
  26.     FILE *ifd;
  27.     pixel **pixels, *pixelrow, onepixel, p;
  28.     register pixel *pP;
  29.     colorhist_vector chv;
  30.     colorhash_table cht;
  31.     int argn, pr_type, xflag, rows, cols, i;
  32.     int depth, colors, linesize, row;
  33.     register int col;
  34.     pixval maxval;
  35.     struct pixrect *pr;
  36.     colormap_t *pr_colormapP;
  37.     short *data, s;
  38.     register short *sp;
  39.     int bitcount, bytenum, color;
  40.     colormap_t *make_pr_colormap();
  41.     char *usage = "[-s] [-x] [ppmfile]";
  42.  
  43.     pm_progname = argv[0];
  44.  
  45.     argn = 1;
  46.     pr_type = RT_BYTE_ENCODED;
  47.     xflag = 0;
  48.  
  49.     while ( argn < argc && argv[argn][0] == '-' )
  50.     {
  51.     if ( ( argv[argn][1] == 's' || argv[argn][1] == 'S' ) &&
  52.          argv[argn][2] == '\0' )
  53.         {
  54.         pr_type = RT_STANDARD;
  55.         argn++;
  56.         }
  57.     else if ( ( argv[argn][1] == 'x' || argv[argn][1] == 'X' ) &&
  58.          argv[argn][2] == '\0' )
  59.         {
  60.         xflag = 1;
  61.         argn++;
  62.         }
  63.     else
  64.         pm_usage( usage );
  65.     }
  66.  
  67.     if ( argn != argc )
  68.     {
  69.     ifd = pm_openr( argv[argn] );
  70.     argn++;
  71.     }
  72.     else
  73.     ifd = stdin;
  74.  
  75.     if ( argn != argc )
  76.     pm_usage( usage );
  77.  
  78.     pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
  79.  
  80.     pm_close( ifd );
  81.  
  82.     /* Figure out the proper depth and colormap. */
  83.     fprintf( stderr, "(Computing colormap..." );
  84.     fflush( stderr );
  85.     chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
  86.     if ( chv == (colorhist_vector) 0 )
  87.     {
  88.     fprintf(
  89.         stderr, "  Too many colors - proceeding to write a 24-bit\n" );
  90.     fprintf(
  91.         stderr, "non-mapped rasterfile.  If you want 8 bits, try running the\n" );
  92.     fprintf( stderr, "pixmap through 'ppmquant 256'.)\n" );
  93.     depth = 24;
  94.     pr_colormapP = (colormap_t *) 0;
  95.     }
  96.     else
  97.     {
  98.     fprintf( stderr, "  Done.  %d colors found.)\n", colors );
  99.  
  100.     if ( maxval != 255 )
  101.         for ( i = 0; i < colors; i++ )
  102.         PPM_CSCALE( chv[i].color, chv[i].color, maxval, 255 );
  103.  
  104.     if ( xflag )
  105.         {
  106.         /* Force black to slot 0 and white to slot 1, if possible. */
  107.         PPM_ASSIGN( p, 0, 0, 0 );
  108.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
  109.         PPM_ASSIGN( p, 255, 255, 255 );
  110.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
  111.         }
  112.     else
  113.         {
  114.         /* Force white to slot 0 and black to slot 1, if possible. */
  115.         PPM_ASSIGN( p, 255, 255, 255 );
  116.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 0 );
  117.         PPM_ASSIGN( p, 0, 0, 0 );
  118.         ppm_addtocolorhist( chv, &colors, MAXCOLORS, p, 0, 1 );
  119.         }
  120.  
  121.     /* Now turn the ppm colormap into the appropriate Sun colormap. */
  122.     if ( colors == 2 )
  123.         {
  124.         /* Monochrome - no problem. */
  125.         depth = 1;
  126.         if ( PPM_GETR( chv[0].color ) == 255 &&
  127.          PPM_GETG( chv[0].color ) == 255 &&
  128.          PPM_GETB( chv[0].color ) == 255 &&
  129.              PPM_GETR( chv[1].color ) == 0 &&
  130.          PPM_GETG( chv[1].color ) == 0 &&
  131.          PPM_GETB( chv[1].color ) == 0 )
  132.         {
  133.         /* Default colormap. */
  134.         pr_colormapP = (colormap_t *) 0;
  135.         }
  136.         else
  137.         pr_colormapP = make_pr_colormap( chv, colors );
  138.         onepixel = chv[1].color;
  139.         }
  140.     else
  141.         {
  142.         depth = 8;
  143.         pr_colormapP = make_pr_colormap( chv, colors );
  144.         cht = ppm_colorhisttocolorhash( chv, colors );
  145.         }
  146.     ppm_freecolorhist( chv );
  147.     }
  148.     if ( maxval > 255 )
  149.     fprintf(
  150.         stderr, "(Maxval is not 255 -- automatically rescaling colors.)\n");
  151.     
  152.     /* Allocate space for the Sun-format image. */
  153.     if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect *) 0 )
  154.     pm_error( "unable to create new pixrect", 0,0,0,0,0 );
  155.     data = ( (struct mpr_data *) pr->pr_data )->md_image;
  156.     linesize = ( (struct mpr_data *) pr->pr_data )->md_linebytes;
  157.  
  158.     /* And compute the Sun image.  The variables at this point are:
  159.     **   chv is null or not
  160.     **   depth is 1, 8, or 24
  161.     */
  162.     for ( row = 0; row < rows; row++ )
  163.     {
  164.     pixelrow = pixels[row];
  165.     sp = data;
  166.     switch ( depth )
  167.         {
  168.         case 1:
  169.         bitcount = 15;
  170.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  171.         {
  172.         if ( maxval != 255 )
  173.             PPM_CSCALE( *pP, *pP, maxval, 255 );
  174.         if ( PPM_EQUAL( *pP, onepixel ) )
  175.             *sp |= 1 << bitcount;
  176.         bitcount--;
  177.         if ( bitcount < 0 )
  178.             {
  179.             sp++;
  180.             bitcount = 15;
  181.             }
  182.         }
  183.         break;
  184.  
  185.         case 8:
  186.         /* If depth is 8, we have a valid cht (yes, t). */
  187.         bytenum = 0;
  188.         s = 0;
  189.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  190.         {
  191.         if ( maxval != 255 )
  192.             PPM_CSCALE( *pP, *pP, maxval, 255 );
  193.         if ( bytenum == 2 )
  194.             {
  195.             sp++;
  196.             bytenum = 0;
  197.             s = 0;
  198.             }
  199.         color = ppm_lookupcolor( cht, *pP );
  200.         if ( color == -1 )
  201.             pm_error(
  202.             "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
  203.             row, col, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP) );
  204.         if ( bytenum == 0 )
  205.             s = color << 8;
  206.         else
  207.             {
  208.             s += color;
  209.             *sp = s;
  210.             }
  211.         bytenum++;
  212.         }
  213.         break;
  214.  
  215.         case 24:
  216.         /* If depth is 24, we are guaranteed NOT to have a valid chv. */
  217.         bytenum = 0;
  218.         s = 0;
  219.         for ( col = 0, pP = pixelrow; col < cols; col++, pP++ )
  220.         {
  221.         if ( maxval != 255 )
  222.             PPM_CSCALE( *pP, *pP, maxval, 255 );
  223.         if ( bytenum == 2 )
  224.             {
  225.             sp++;
  226.             bytenum = 0;
  227.             s = 0;
  228.             }
  229.         if ( bytenum == 0 )
  230.             s = PPM_GETR( *pP ) << 8;
  231.         else
  232.             {
  233.             s += PPM_GETR( *pP );
  234.             *sp = s;
  235.             }
  236.         bytenum++;
  237.         if ( bytenum == 2 )
  238.             {
  239.             sp++;
  240.             bytenum = 0;
  241.             s = 0;
  242.             }
  243.         if ( bytenum == 0 )
  244.             s = PPM_GETG( *pP ) << 8;
  245.         else
  246.             {
  247.             s += PPM_GETG( *pP );
  248.             *sp = s;
  249.             }
  250.         bytenum++;
  251.         if ( bytenum == 2 )
  252.             {
  253.             sp++;
  254.             bytenum = 0;
  255.             s = 0;
  256.             }
  257.         if ( bytenum == 0 )
  258.             s = PPM_GETB( *pP ) << 8;
  259.         else
  260.             {
  261.             s += PPM_GETB( *pP );
  262.             *sp = s;
  263.             }
  264.         bytenum++;
  265.         }
  266.         break;
  267.  
  268.         default:
  269.         pm_error( "can't happen", 0,0,0,0,0 );
  270.         }
  271.     data += linesize / sizeof(short);
  272.     }
  273.  
  274. #ifdef sun386
  275.     /* Force a flip to 80386 format. */
  276.     ( (struct mpr_data *) pr->pr_data )->md_flags &= ! MP_I386;
  277.     pr_flip( pr );
  278. #endif sun386
  279.  
  280.     /* Finally, write the sucker out. */
  281.     pr_dump( pr, stdout, pr_colormapP, pr_type, 0 );
  282.  
  283.     exit( 0 );
  284.     }
  285.  
  286. colormap_t *
  287. make_pr_colormap( chv, colors )
  288. colorhist_vector chv;
  289. int colors;
  290.     {
  291.     colormap_t *pr_colormapP;
  292.     int i;
  293.  
  294.     pr_colormapP = (colormap_t *) malloc( sizeof(colormap_t) );
  295.     if ( pr_colormapP == 0 )
  296.     pm_error( "out of memory", 0,0,0,0,0 );
  297.     pr_colormapP->type = RMT_EQUAL_RGB;
  298.     pr_colormapP->length = colors;
  299.     pr_colormapP->map[0] =
  300.     (unsigned char *) malloc( colors * sizeof(unsigned char) );
  301.     pr_colormapP->map[1] =
  302.     (unsigned char *) malloc( colors * sizeof(unsigned char) );
  303.     pr_colormapP->map[2] =
  304.     (unsigned char *) malloc( colors * sizeof(unsigned char) );
  305.     if ( pr_colormapP->map[0] == 0 || pr_colormapP->map[1] == 0 ||
  306.      pr_colormapP->map[2] == 0 )
  307.     pm_error( "out of memory", 0,0,0,0,0 );
  308.  
  309.     for ( i = 0; i < colors; i++ )
  310.     {
  311.     pr_colormapP->map[0][i] = PPM_GETR( chv[i].color );
  312.     pr_colormapP->map[1][i] = PPM_GETG( chv[i].color );
  313.     pr_colormapP->map[2][i] = PPM_GETB( chv[i].color );
  314.     }
  315.  
  316.     return pr_colormapP;
  317.     }
  318.  
  319. #ifdef notdef
  320. dump_map( chv, colors )
  321. colorhist_vector chv;
  322. int colors;
  323.     {
  324.     int i;
  325.  
  326.     for ( i = 0; i < colors; i++ )
  327.     fprintf(
  328.         stderr, "%d: %d %d %d  (%d)\n", i, PPM_GETR(chv[i].color),
  329.         PPM_GETG(chv[i].color), PPM_GETB(chv[i].color), chv[i].count );
  330.     }
  331. #endif notdef
  332.