IXBM.c
资源名称:ilib [点击查看]
上传用户:changbiao
上传日期:2007-01-13
资源大小:141k
文件大小:7k
源码类别:

图片显示

开发平台:

C/C++

  1. /*
  2.  * IXBM.c
  3.  *
  4.  * Image library
  5.  *
  6.  * Description:
  7.  * Read/write XBM files.
  8.  *
  9.  * History:
  10.  * 27-Aug-99 Craig Knudsen cknudsen@radix.net
  11.  * Created
  12.  *
  13.  ****************************************************************************/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include <memory.h>
  18. #include <string.h>
  19. #include "Ilib.h"
  20. #include "IlibP.h"
  21. IError _IWriteXBM ( fp, image, options )
  22. FILE *fp;
  23. IImageP *image;
  24. IOptions options;
  25. {
  26.   int r, c;
  27.   unsigned char red, green, blue;
  28.   int val;
  29.   int bit;
  30.   int numchars = 0;
  31.   fprintf ( fp, "#define image_width %dn", image->width );
  32.   fprintf ( fp, "#define image_height %dn", image->height );
  33.   fprintf ( fp, "static char image_bits[] = {n" );
  34.   bit = 1;
  35.   num_chars = 0;
  36.   for ( r = 0; r < image->height; r++ ) {
  37.     for ( c = 0; c < image->width; c++, bit++ ) {
  38.       if ( bit > 8 )
  39.         bit = 1;
  40.       offset = ( r * image->width ) + c;
  41.       if ( image->greyscale ) {
  42.         ptr = image->data + ( r * image->width ) + c;
  43.         red = green = blue = (unsigned int) *ptr;
  44.       }
  45.       else {
  46.         ptr = image->data + ( r * image->width * 3 ) + ( c * 3 );
  47.         red = (unsigned int) *ptr;
  48.         green = (unsigned int) *( ptr + 1 );
  49.         blue = (unsigned int) *( ptr + 2 );
  50.       }
  51.       if ( (int)red + (int)green + (int)blue > 384 ) {
  52.         val |= ( 0x01 << bit );
  53.       }
  54.       if ( bit == 8 ) {
  55.         if ( numchars )
  56.           fprintf ( fp, ", " );
  57.         numchars++;
  58.         if ( numchars == 12 ) {
  59.           fprintf ( fp, "n   " );
  60.           numchars = 0;
  61.         }
  62.         fprintf ( fp, "0x%02X" val );
  63.       }
  64.     }
  65.     if ( bit < 9 ) {
  66.       fprintf ( fp, ", 0x
  67.     }
  68.   }
  69.   fprintf ( fp, "/* colors */n" );
  70.   for ( loop = 0; loop < num_colors; loop++ ) {
  71.     if ( image->transparent != NULL &&
  72.       ( image->transparent->red == colormap[loop]->red &&
  73.       image->transparent->green == colormap[loop]->green &&
  74.       image->transparent->blue == colormap[loop]->blue ) )
  75.       strcpy ( colorstr, "None" );
  76.     else
  77.       sprintf ( colorstr, "#%02X%02X%02X", colormap[loop]->red,
  78.         colormap[loop]->green, colormap[loop]->blue );
  79.     switch ( chars_per_pixel ) {
  80.       case 1:
  81.         fprintf ( fp, ""%c c %s",n", xpm_chars[loop], colorstr );
  82.         break;
  83.       case 2:
  84.         fprintf ( fp, ""%c%c c %s",n",
  85.           xpm_chars[loop/strlen(xpm_chars)],
  86.           xpm_chars[loop%strlen(xpm_chars)], colorstr );
  87.         break;
  88.     }
  89.   }
  90.   fprintf ( fp, "/* pixels */n" );
  91.   for ( loop = 0; loop < image->height; loop++ ) {
  92.     fprintf ( fp, """ );
  93.     for ( loop2 = 0; loop2 < image->width; loop2++ ) {
  94.       switch ( chars_per_pixel ) {
  95.         case 1:
  96.           fprintf ( fp, "%c", xpm_chars[data[loop*image->width+loop2]] );
  97.           break;
  98.         case 2:
  99.           fprintf ( fp, "%c%c",
  100.             xpm_chars[data[loop*image->width+loop2]/strlen(xpm_chars)],
  101.             xpm_chars[data[loop*image->width+loop2]%strlen(xpm_chars)] );
  102.           break;
  103.       }
  104.     }
  105.     fprintf ( fp, "",n" );
  106.   }
  107.   fprintf ( fp, "};n" );
  108.   /* free up allocated resources */
  109.   free ( data );
  110.   for ( loop = 0; loop < num_colors; loop++ ) {
  111.     free ( colormap[loop] );
  112.   }
  113.   return ( INoError );
  114. }
  115. static unsigned char hextochar ( hex )
  116. char hex;
  117. {
  118.   switch ( toupper ( hex ) ) {
  119.     case '0': return 0;
  120.     case '1': return 1;
  121.     case '2': return 2;
  122.     case '3': return 3;
  123.     case '4': return 4;
  124.     case '5': return 5;
  125.     case '6': return 6;
  126.     case '7': return 7;
  127.     case '8': return 8;
  128.     case '9': return 9;
  129.     case 'A': return 10;
  130.     case 'B': return 11;
  131.     case 'C': return 12;
  132.     case 'D': return 13;
  133.     case 'E': return 14;
  134.     case 'F': return 15;
  135.   }
  136.   return 0;
  137. }
  138. static int parse_color ( str, r, g, b, is_transparent )
  139. char *str;
  140. unsigned char *r, *g, *b;
  141. int *is_transparent;
  142. {
  143.   char *ptr;
  144.   int w;
  145.   for ( ptr = str; *ptr != ''; ptr++ )
  146.     *ptr = tolower ( *ptr );
  147.   *is_transparent = 0;
  148.   if ( *str == '#' ) {
  149.     ptr = str + 1;
  150.     w = strlen ( str ) / 3;
  151.     *r = hextochar ( ptr[0] ) * 16 + hextochar ( ptr[1] );
  152.     ptr += w;
  153.     *g = hextochar ( ptr[0] ) * 16 + hextochar ( ptr[1] );
  154.     ptr += w;
  155.     *b = hextochar ( ptr[0] ) * 16 + hextochar ( ptr[1] );
  156.     return 0;
  157.   } else if ( strcmp ( str, "none" ) == 0 ||
  158.     strcmp ( str, "transparent" ) == 0 ) {
  159.     *r = *g = *b = 254; /* don't make white since it might already exist */
  160.     *is_transparent = 1;
  161.     return 0;
  162.   } else {
  163.     /* name like "blue" */
  164.     return 1;
  165.   }
  166. }
  167. typedef struct {
  168.   char *abbrev;
  169.   unsigned char r;
  170.   unsigned char g;
  171.   unsigned char b;
  172.   int transparent;
  173. } xpmcolor;
  174. IError _IReadXPM ( fp, options, image_return )
  175. FILE *fp;
  176. IOptions options;
  177. IImageP **image_return;
  178. {
  179.   IImageP *image = NULL;
  180.   char line[1024], *ptr, *r, *g, *b, *cur;
  181.   xpmcolor *colors = NULL;
  182.   int w, h, num_colors, colorw, loop, loop2, loop3;
  183.   int found;
  184.   IColor t;
  185.   /* look for first line that starts with " */
  186.   while ( fgets ( line, 1024, fp ) ) {
  187.     if ( line[0] == '"' )
  188.       break;
  189.   }
  190.   if ( line[0] != '"' )
  191.     return IInvalidFormat;
  192.   ptr = strtok ( line + 1, " " );
  193.   if ( ! ptr )
  194.     return IInvalidFormat;
  195.   w = atoi ( ptr );
  196.   ptr = strtok ( NULL, " " );
  197.   if ( ! ptr )
  198.     return IInvalidFormat;
  199.   h = atoi ( ptr );
  200.   ptr = strtok ( NULL, " " );
  201.   if ( ! ptr )
  202.     return IInvalidFormat;
  203.   num_colors = atoi ( ptr );
  204.   ptr = strtok ( NULL, " " );
  205.   if ( ! ptr )
  206.     return IInvalidFormat;
  207.   colorw = atoi ( ptr );
  208.   colors = (xpmcolor *) malloc ( sizeof ( xpmcolor ) * num_colors );
  209.   for ( loop = 0; loop < num_colors; loop++ ) {
  210.     while ( 1 ) {
  211.       if ( ! fgets ( line, 1024, fp ) )
  212.         return IInvalidFormat; /* small memory leak */
  213.       if ( line[0] == '"' )
  214.         break;
  215.     }
  216.     colors[loop].abbrev = (char *) malloc ( colorw + 1 );
  217.     strncpy ( colors[loop].abbrev, line + 1, colorw );
  218.     colors[loop].abbrev[colorw] = '';
  219.     for ( ptr = line + 1 + colorw; *ptr != 'c' && *ptr != ''; ptr++ ) ;
  220.     if ( *ptr != 'c' )
  221.       return IInvalidFormat; /* small memory leak */
  222.     do {
  223.       ptr++;
  224.     } while ( *ptr == ' ' );
  225.     strtok ( ptr, """ );
  226.     /* parse color */
  227.     if ( parse_color ( ptr, &colors[loop].r, &colors[loop].g, &colors[loop].b,
  228.       &colors[loop].transparent ) )
  229.       return IInvalidFormat; /* small memory leak */
  230.   }
  231.   image = (IImageP *) ICreateImage ( w, h, options );
  232.   /* now read row by row of data */
  233.   ptr = (char *) malloc ( colorw * w + 20 );
  234.   for ( loop = 0; loop < h; loop++ ) {
  235.     if ( ! fgets ( ptr, colorw * w + 20, fp ) )
  236.       return IInvalidFormat; /* small memory leak */
  237.     while ( ptr[0] != '"' ) {
  238.       if ( ! fgets ( ptr, colorw * w + 20, fp ) )
  239.         return IInvalidFormat; /* small memory leak */
  240.     }
  241.     for ( loop2 = 0; loop2 < w; loop2++ ) {
  242.       cur = ptr + 1 + loop2 * colorw;
  243.       /* find color in colormap */
  244.       for ( loop3 = 0, found = 0; loop3 < num_colors && ! found; loop3++ ) {
  245.         if ( strncmp ( colors[loop3].abbrev, cur, colorw ) == 0 ) {
  246.           r = image->data + ( loop * w * 3 ) + ( loop2 * 3 );
  247.           g = r + 1;
  248.           b = r + 2;
  249.           *r = colors[loop3].r;
  250.           *g = colors[loop3].g;
  251.           *b = colors[loop3].b;
  252.           found = 1;
  253.         }
  254.       }
  255.       if ( ! found )
  256.         return IInvalidFormat; /* small memory leak */
  257.     }
  258.   }
  259.   free ( ptr );
  260.   *image_return = image;
  261.   for ( loop = 0; loop < num_colors; loop++ ) {
  262.     if ( colors[loop].transparent ) {
  263.       t = IAllocColor ( colors[loop].r, colors[loop].g, colors[loop].b );
  264.       ISetTransparent ( image, t );
  265.     }
  266.     free ( colors[loop].abbrev );
  267.   }
  268.   free ( colors );
  269.   return ( INoError );
  270. }