home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / fontutils-0.6 / imageto / input-img.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-14  |  4.4 KB  |  153 lines

  1. /* input-img.c: read Interleaf .img files.
  2.  
  3. Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include "file-input.h"
  22.  
  23. #include "main.h"
  24. #include "image-header.h"
  25. #include "input-img.h"
  26.  
  27.  
  28. /* Where the input comes from.  */
  29. static FILE *img_input_file;
  30. static string img_input_filename;
  31.  
  32. /* What we'll read the raw data for each scanline into.  */
  33. static one_byte *line_in_bytes;
  34.  
  35. /* How big `line_in_bytes' is, in both bytes and bits.  */
  36. static unsigned byte_width;
  37. static unsigned bit_width;
  38.  
  39. /* Macros for convenient input.  The routines are defined in kbase.  */
  40. #define IMG_MATCH_BYTE(v)  match_byte (v, img_input_file, img_input_filename)
  41.  
  42. #define IMG_GET_TWO()  get_two (img_input_file, img_input_filename)
  43. #define IMG_GET_FOUR()  get_four (img_input_file, img_input_filename)
  44.  
  45. /* Only one file can be open at a time.  We do no path searching.  If
  46.    FILENAME can't be opened, we quit.  */
  47.  
  48. void
  49. img_open_input_file (string filename)
  50. {
  51.   assert (img_input_file == NULL);
  52.   
  53.   img_input_file = xfopen (filename, "r");
  54.   img_input_filename = filename;
  55. }
  56.  
  57.  
  58. /* Close the input file.  If it hasn't been opened, we quit.  */
  59.  
  60. void
  61. img_close_input_file ()
  62. {
  63.   assert (img_input_file != NULL);
  64.   
  65.   xfclose (img_input_file, img_input_filename);
  66.   img_input_file = NULL;
  67. }
  68.  
  69. /* Read the header information.  
  70.    Modifies the global image_header in main.c.  */
  71.  
  72. void
  73. img_get_header ()
  74. {
  75.   unsigned short_width;
  76.   unsigned flags;
  77.   
  78.   /* The ``magic number''.  */
  79.   IMG_MATCH_BYTE (0211);
  80.   IMG_MATCH_BYTE ('O');
  81.   IMG_MATCH_BYTE ('P');
  82.   IMG_MATCH_BYTE ('S');
  83.   
  84.   /* The version number.  */
  85.   IMG_MATCH_BYTE (0);
  86.   IMG_MATCH_BYTE (2);
  87.   
  88.   image_header.hres = IMG_GET_TWO ();
  89.   image_header.vres = IMG_GET_TWO ();
  90.   flags = IMG_GET_FOUR ();
  91.   if (flags != 0)
  92.     FATAL1 ("img_get_header: Expected flags to be zero, not %u", flags);
  93.   image_header.width = IMG_GET_TWO ();
  94.   image_header.height = IMG_GET_TWO ();
  95.   image_header.depth = IMG_GET_TWO ();
  96.   if (image_header.depth != 1)
  97.     FATAL1 ("img_get_header: I can't handle %u-bit deep images", 
  98.         image_header.depth);
  99.   image_header.format = IMG_GET_TWO ();
  100.   if (image_header.format != 0)
  101.     FATAL1 ("img_get_header: Expected format to be zero, not %u", 
  102.         image_header.format);
  103.   
  104.   /* Allocate the space that we will read into (since that space is the
  105.      same from scanline to scanline).  The width is derived from the
  106.      header information, which must already have been read.
  107.      Specifically, the width in the header is given in bits.  Each
  108.      scanline is padded to a 16-bit boundary.  For example, suppose the
  109.      header width = 1516, that is 94.75 shorts; we round up to 95,
  110.      thus getting a scanline width of 1520 bits, or 190 bytes.  */
  111.  
  112.   bit_width = image_header.width;
  113.   short_width = bit_width / 16 + (bit_width % 16 != 0);
  114.   byte_width = short_width * 2;
  115.   line_in_bytes = xmalloc (byte_width);
  116. }
  117.  
  118. /* Read one scanline of the image, returning each bit of the scanline in
  119.    a separate byte.  We use the `line_in_bytes' variable, allocated in
  120.    `img_get_header', to read into.  */
  121.  
  122. boolean
  123. img_get_scanline (one_byte *line_in_bits)
  124. {
  125.   unsigned this_bit, this_byte, mask;
  126.  
  127.   if (fread (line_in_bytes, byte_width, 1, img_input_file) != 1)
  128.     {
  129.       if (feof (img_input_file))
  130.         return false;
  131.       else
  132.         FATAL1 ("img_get_scanline: fread of %u bytes failed", byte_width);
  133.     }
  134.   
  135.   for (this_bit = 0, this_byte = 0, mask = 0x80;
  136.        this_bit < bit_width; this_bit++)
  137.     {
  138.       /* Somewhere along the line, black and white got reversed.  */
  139.       line_in_bits[this_bit] = (line_in_bytes[this_byte] & mask) == 0;
  140.       if (this_bit % 8 == 0)
  141.         {
  142.           this_byte = this_bit / 8;
  143.           mask = 0x80;
  144.         }
  145.       else
  146.         mask >>= 1;
  147.     }
  148.  
  149.   print_scanline (line_in_bits, bit_width);
  150.  
  151.   return true;
  152. }
  153.