home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / libpnm4.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  10KB  |  454 lines

  1. /* libpnm4.c - pnm utility library part 4
  2. **
  3. ** Copyright (C) 1988 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 "pnm.h"
  14. #include "rast.h"
  15.  
  16. /*
  17. ** Semi-work-alike versions of some Sun pixrect routines.  Just enough
  18. ** for rasterfile reading and writing to work.
  19. */
  20.  
  21. struct pixrect*
  22. mem_create( w, h, depth )
  23.     int w, h, depth;
  24.     {
  25.     struct pixrect* p;
  26.     struct mpr_data* m;
  27.  
  28.     p = (struct pixrect*) malloc( sizeof(struct pixrect) );
  29.     if ( p == NULL )
  30.     return NULL;
  31.     p->pr_ops = NULL;
  32.     p->pr_size.x = w;
  33.     p->pr_size.y = h;
  34.     p->pr_depth = depth;
  35.     m = p->pr_data = (struct mpr_data*) malloc( sizeof(struct mpr_data) );
  36.     if ( m == NULL )
  37.     {
  38.     free( p );
  39.     return NULL;
  40.     }
  41.     /* According to the documentation, linebytes is supposed to be rounded
  42.     ** up to a longword (except on 386 boxes).  However, this turns out
  43.     ** not to be the case.  In reality, all of Sun's code rounds up to
  44.     ** a short, not a long.
  45.     */
  46.     m->md_linebytes = ( w * depth + 15 ) / 16 * 2;
  47.     m->md_offset.x = 0;
  48.     m->md_offset.y = 0;
  49.     m->md_flags = 0;
  50.     m->md_image = (unsigned char*) malloc( m->md_linebytes * h );
  51.     if ( m->md_image == NULL )
  52.     {
  53.     free( m );
  54.     free( p );
  55.     return NULL;
  56.     }
  57.  
  58.     return p;
  59.     }
  60.  
  61. void
  62. mem_free( p )
  63.     struct pixrect* p;
  64.     {
  65.     free( p->pr_data->md_image );
  66.     free( p->pr_data );
  67.     free( p );
  68.     }
  69.  
  70. int
  71. pr_dump( p, out, colormap, type, copy_flag )
  72.     struct pixrect* p;
  73.     FILE* out;
  74.     colormap_t* colormap;
  75.     int type, copy_flag;
  76.     {
  77.     struct rasterfile h;
  78.     int size, besize, count;
  79.     unsigned char* beimage;
  80.     unsigned char* bp;
  81.     unsigned char c, pc;
  82.     int i, j;
  83.  
  84.     h.ras_magic = RAS_MAGIC;
  85.     h.ras_width = p->pr_size.x;
  86.     h.ras_height = p->pr_size.y;
  87.     h.ras_depth = p->pr_depth;
  88.  
  89.     h.ras_type = type;
  90.     switch ( type )
  91.     {
  92.     case RT_OLD:
  93.     pm_error( "old rasterfile type is not supported" );
  94.  
  95.     case RT_FORMAT_TIFF:
  96.     pm_error( "tiff rasterfile type is not supported" );
  97.  
  98.     case RT_FORMAT_IFF:
  99.     pm_error( "iff rasterfile type is not supported" );
  100.  
  101.     case RT_EXPERIMENTAL:
  102.     pm_error( "experimental rasterfile type is not supported" );
  103.  
  104.     case RT_STANDARD:
  105.     case RT_FORMAT_RGB:
  106.     /* Ignore hP->ras_length. */
  107.     h.ras_length = p->pr_size.y * p->pr_data->md_linebytes;
  108.     break;
  109.  
  110.     case RT_BYTE_ENCODED:
  111.     size = p->pr_size.y * p->pr_data->md_linebytes;
  112.     bp = p->pr_data->md_image;
  113.     beimage = (unsigned char*) malloc( size * 3 / 2 );    /* worst case */
  114.     if ( beimage == NULL )
  115.         return PIX_ERR;
  116.     besize = 0;
  117.     count = 0;
  118.     for ( i = 0; i < size; ++i )
  119.         {
  120.         c = *bp++;
  121.         if ( count > 0 )
  122.         {
  123.         if ( pc != c )
  124.             {
  125.             if ( count == 1 && pc == 128 )
  126.             {
  127.             beimage[besize++] = 128;
  128.             beimage[besize++] = 0;
  129.             count = 0;
  130.             }
  131.             else if ( count > 2 || pc == 128 )
  132.             {
  133.             beimage[besize++] = 128;
  134.             beimage[besize++] = count - 1;
  135.             beimage[besize++] = pc;
  136.             count = 0;
  137.             }
  138.             else
  139.             {
  140.             for ( j = 0; j < count; ++j )
  141.                 beimage[besize++] = pc;
  142.             count = 0;
  143.             }
  144.             }
  145.         }
  146.         pc = c;
  147.         ++count;
  148.         if ( count == 256 )
  149.         {
  150.         beimage[besize++] = 128;
  151.         beimage[besize++] = count - 1;
  152.         beimage[besize++] = c;
  153.         count = 0;
  154.         }
  155.         }
  156.     if ( count > 0 )
  157.         {
  158.         if ( count == 1 && c == 128 )
  159.         {
  160.         beimage[besize++] = 128;
  161.         beimage[besize++] = 0;
  162.         }
  163.         if ( count > 2 || c == 128 )
  164.         {
  165.         beimage[besize++] = 128;
  166.         beimage[besize++] = count - 1;
  167.         beimage[besize++] = c;
  168.         }
  169.         else
  170.         {
  171.         for ( j = 0; j < count; ++j )
  172.             beimage[besize++] = c;
  173.         }
  174.         }
  175.     h.ras_length = besize;
  176.     break;
  177.  
  178.     default:
  179.     pm_error( "unknown rasterfile type" );
  180.     }
  181.  
  182.     if ( colormap == NULL )
  183.     {
  184.     h.ras_maptype = RMT_NONE;
  185.     h.ras_maplength = 0;
  186.     }
  187.     else
  188.     {
  189.     h.ras_maptype = colormap->type;
  190.     switch ( colormap->type )
  191.         {
  192.         case RMT_EQUAL_RGB:
  193.         h.ras_maplength = colormap->length * 3;
  194.         break;
  195.  
  196.         case RMT_RAW:
  197.         h.ras_maplength = colormap->length;
  198.         break;
  199.  
  200.         default:
  201.         pm_error( "unknown colormap type" );
  202.         }
  203.     }
  204.  
  205.     if ( pm_writebiglong( out, h.ras_magic ) == -1 )
  206.     return PIX_ERR;
  207.     if ( pm_writebiglong( out, h.ras_width ) == -1 )
  208.     return PIX_ERR;
  209.     if ( pm_writebiglong( out, h.ras_height ) == -1 )
  210.     return PIX_ERR;
  211.     if ( pm_writebiglong( out, h.ras_depth ) == -1 )
  212.     return PIX_ERR;
  213.     if ( pm_writebiglong( out, h.ras_length ) == -1 )
  214.     return PIX_ERR;
  215.     if ( pm_writebiglong( out, h.ras_type ) == -1 )
  216.     return PIX_ERR;
  217.     if ( pm_writebiglong( out, h.ras_maptype ) == -1 )
  218.     return PIX_ERR;
  219.     if ( pm_writebiglong( out, h.ras_maplength ) == -1 )
  220.     return PIX_ERR;
  221.  
  222.     if ( colormap != NULL )
  223.     {
  224.     switch ( colormap->type )
  225.         {
  226.         case RMT_EQUAL_RGB:
  227.         if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
  228.          colormap->length )
  229.         return PIX_ERR;
  230.         if ( fwrite( colormap->map[1], 1, colormap->length, out ) !=
  231.          colormap->length )
  232.         return PIX_ERR;
  233.         if ( fwrite( colormap->map[2], 1, colormap->length, out ) !=
  234.          colormap->length )
  235.         return PIX_ERR;
  236.         break;
  237.  
  238.         case RMT_RAW:
  239.         if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
  240.          colormap->length )
  241.         return PIX_ERR;
  242.         break;
  243.         }
  244.     }
  245.  
  246.     switch ( type )
  247.     {
  248.     case RT_STANDARD:
  249.     case RT_FORMAT_RGB:
  250.     if ( fwrite( p->pr_data->md_image, 1, h.ras_length, out ) !=
  251.          h.ras_length )
  252.         return PIX_ERR;
  253.     break;
  254.  
  255.     case RT_BYTE_ENCODED:
  256.     if ( fwrite( beimage, 1, besize, out ) != besize )
  257.         {
  258.         free( beimage );
  259.         return PIX_ERR;
  260.         }
  261.     free( beimage );
  262.     break;
  263.     }
  264.  
  265.     return 0;
  266.     }
  267.  
  268. int
  269. pr_load_header( in, hP )
  270.     FILE* in;
  271.     struct rasterfile* hP;
  272.     {
  273.     if ( pm_readbiglong( in, &(hP->ras_magic) ) == -1 )
  274.     return PIX_ERR;
  275.     if ( hP->ras_magic != RAS_MAGIC )
  276.     return PIX_ERR;
  277.     if ( pm_readbiglong( in, &(hP->ras_width) ) == -1 )
  278.     return PIX_ERR;
  279.     if ( pm_readbiglong( in, &(hP->ras_height) ) == -1 )
  280.     return PIX_ERR;
  281.     if ( pm_readbiglong( in, &(hP->ras_depth) ) == -1 )
  282.     return PIX_ERR;
  283.     if ( pm_readbiglong( in, &(hP->ras_length) ) == -1 )
  284.     return PIX_ERR;
  285.     if ( pm_readbiglong( in, &(hP->ras_type) ) == -1 )
  286.     return PIX_ERR;
  287.     if ( pm_readbiglong( in, &(hP->ras_maptype) ) == -1 )
  288.     return PIX_ERR;
  289.     if ( pm_readbiglong( in, &(hP->ras_maplength) ) == -1 )
  290.     return PIX_ERR;
  291.     return 0;
  292.     }
  293.  
  294. int
  295. pr_load_colormap( in, hP, colormap )
  296.     FILE* in;
  297.     struct rasterfile* hP;
  298.     colormap_t* colormap;
  299.     {
  300.     if ( colormap == NULL || hP->ras_maptype == RMT_NONE )
  301.     {
  302.     int i;
  303.  
  304.     for ( i = 0; i < hP->ras_maplength; ++i )
  305.         if ( getc( in ) == EOF )
  306.         return PIX_ERR;
  307.     }
  308.     else
  309.     {
  310.     colormap->type = hP->ras_maptype;
  311.     switch ( hP->ras_maptype )
  312.         {
  313.         case RMT_EQUAL_RGB:
  314.         colormap->length = hP->ras_maplength / 3;
  315.         colormap->map[0] = (unsigned char*) malloc( colormap->length );
  316.         if ( colormap->map[0] == NULL )
  317.         return PIX_ERR;
  318.         colormap->map[1] = (unsigned char*) malloc( colormap->length );
  319.         if ( colormap->map[1] == NULL )
  320.         {
  321.         free( colormap->map[0] );
  322.         return PIX_ERR;
  323.         }
  324.         colormap->map[2] = (unsigned char*) malloc( colormap->length );
  325.         if ( colormap->map[2] == NULL )
  326.         {
  327.         free( colormap->map[0] );
  328.         free( colormap->map[1] );
  329.         return PIX_ERR;
  330.         }
  331.         if ( fread( colormap->map[0], 1, colormap->length, in ) != colormap->length ||
  332.              fread( colormap->map[1], 1, colormap->length, in ) != colormap->length ||
  333.              fread( colormap->map[2], 1, colormap->length, in ) != colormap->length )
  334.         {
  335.         free( colormap->map[0] );
  336.         free( colormap->map[1] );
  337.         free( colormap->map[2] );
  338.         return PIX_ERR;
  339.         }
  340.         break;
  341.  
  342.         case RMT_RAW:
  343.         colormap->length = hP->ras_maplength;
  344.         colormap->map[0] = (unsigned char*) malloc( colormap->length );
  345.         if ( colormap->map[0] == NULL )
  346.         return PIX_ERR;
  347.         colormap->map[2] = colormap->map[1] = colormap->map[0];
  348.         if ( fread( colormap->map[0], 1, hP->ras_maplength, in ) != hP->ras_maplength )
  349.         {
  350.         free( colormap->map[0] );
  351.         return PIX_ERR;
  352.         }
  353.         break;
  354.  
  355.         default:
  356.         pm_error( "unknown colormap type" );
  357.         }
  358.     }
  359.     return 0;
  360.     }
  361.  
  362. struct pixrect*
  363. pr_load_image( in, hP, colormap )
  364.     FILE* in;
  365.     struct rasterfile* hP;
  366.     colormap_t* colormap;
  367.     {
  368.     struct pixrect* p;
  369.     unsigned char* beimage;
  370.     register unsigned char* bep;
  371.     register unsigned char* bp;
  372.     register unsigned char c;
  373.     int i;
  374.     register int j, count;
  375.  
  376.     p = mem_create( hP->ras_width, hP->ras_height, hP->ras_depth );
  377.     if ( p == NULL )
  378.     return NULL;
  379.  
  380.     switch ( hP->ras_type )
  381.     {
  382.     case RT_OLD:
  383.     pm_error( "old rasterfile type is not supported" );
  384.  
  385.     case RT_FORMAT_TIFF:
  386.     pm_error( "tiff rasterfile type is not supported" );
  387.  
  388.     case RT_FORMAT_IFF:
  389.     pm_error( "iff rasterfile type is not supported" );
  390.  
  391.     case RT_EXPERIMENTAL:
  392.     pm_error( "experimental rasterfile type is not supported" );
  393.  
  394.     case RT_STANDARD:
  395.     case RT_FORMAT_RGB:
  396.     /* Ignore hP->ras_length. */
  397.     i = p->pr_size.y * p->pr_data->md_linebytes;
  398.     if ( fread( p->pr_data->md_image, 1, i, in ) != i )
  399.         {
  400.         mem_free( p );
  401.         return NULL;
  402.         }
  403.     break;
  404.  
  405.     case RT_BYTE_ENCODED:
  406.     beimage = (unsigned char*) malloc( hP->ras_length );
  407.     if ( beimage == NULL )
  408.         {
  409.         mem_free( p );
  410.         return NULL;
  411.         }
  412.     if ( fread( beimage, 1, hP->ras_length, in ) != hP->ras_length )
  413.         {
  414.         mem_free( p );
  415.         free( beimage );
  416.         return NULL;
  417.         }
  418.     bep = beimage;
  419.     bp = p->pr_data->md_image;
  420.     for ( i = 0; i < hP->ras_length; )
  421.         {
  422.         c = *bep++;
  423.         if ( c == 128 )
  424.         {
  425.         count = ( *bep++ ) + 1;
  426.         if ( count == 1 )
  427.             {
  428.             *bp++ = 128;
  429.             i += 2;
  430.             }
  431.         else
  432.             {
  433.             c = *bep++;
  434.             for ( j = 0; j < count; ++j )
  435.             *bp++ = c;
  436.             i += 3;
  437.             }
  438.         }
  439.         else
  440.         {
  441.         *bp++ = c;
  442.         ++i;
  443.         }
  444.         }
  445.     free( beimage );
  446.     break;
  447.  
  448.     default:
  449.     pm_error( "unknown rasterfile type" );
  450.     }
  451.  
  452.     return p;
  453.     }
  454.