home *** CD-ROM | disk | FTP | other *** search
- /* input-img.c: read Interleaf .img files.
-
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "config.h"
-
- #include "file-input.h"
-
- #include "main.h"
- #include "image-header.h"
- #include "input-img.h"
-
-
- /* Where the input comes from. */
- static FILE *img_input_file;
- static string img_input_filename;
-
- /* What we'll read the raw data for each scanline into. */
- static one_byte *line_in_bytes;
-
- /* How big `line_in_bytes' is, in both bytes and bits. */
- static unsigned byte_width;
- static unsigned bit_width;
-
- /* Macros for convenient input. The routines are defined in kbase. */
- #define IMG_MATCH_BYTE(v) match_byte (v, img_input_file, img_input_filename)
-
- #define IMG_GET_TWO() get_two (img_input_file, img_input_filename)
- #define IMG_GET_FOUR() get_four (img_input_file, img_input_filename)
-
- /* Only one file can be open at a time. We do no path searching. If
- FILENAME can't be opened, we quit. */
-
- void
- img_open_input_file (string filename)
- {
- assert (img_input_file == NULL);
-
- img_input_file = xfopen (filename, "r");
- img_input_filename = filename;
- }
-
-
- /* Close the input file. If it hasn't been opened, we quit. */
-
- void
- img_close_input_file ()
- {
- assert (img_input_file != NULL);
-
- xfclose (img_input_file, img_input_filename);
- img_input_file = NULL;
- }
-
- /* Read the header information.
- Modifies the global image_header in main.c. */
-
- void
- img_get_header ()
- {
- unsigned short_width;
- unsigned flags;
-
- /* The ``magic number''. */
- IMG_MATCH_BYTE (0211);
- IMG_MATCH_BYTE ('O');
- IMG_MATCH_BYTE ('P');
- IMG_MATCH_BYTE ('S');
-
- /* The version number. */
- IMG_MATCH_BYTE (0);
- IMG_MATCH_BYTE (2);
-
- image_header.hres = IMG_GET_TWO ();
- image_header.vres = IMG_GET_TWO ();
- flags = IMG_GET_FOUR ();
- if (flags != 0)
- FATAL1 ("img_get_header: Expected flags to be zero, not %u", flags);
- image_header.width = IMG_GET_TWO ();
- image_header.height = IMG_GET_TWO ();
- image_header.depth = IMG_GET_TWO ();
- if (image_header.depth != 1)
- FATAL1 ("img_get_header: I can't handle %u-bit deep images",
- image_header.depth);
- image_header.format = IMG_GET_TWO ();
- if (image_header.format != 0)
- FATAL1 ("img_get_header: Expected format to be zero, not %u",
- image_header.format);
-
- /* Allocate the space that we will read into (since that space is the
- same from scanline to scanline). The width is derived from the
- header information, which must already have been read.
- Specifically, the width in the header is given in bits. Each
- scanline is padded to a 16-bit boundary. For example, suppose the
- header width = 1516, that is 94.75 shorts; we round up to 95,
- thus getting a scanline width of 1520 bits, or 190 bytes. */
-
- bit_width = image_header.width;
- short_width = bit_width / 16 + (bit_width % 16 != 0);
- byte_width = short_width * 2;
- line_in_bytes = xmalloc (byte_width);
- }
-
- /* Read one scanline of the image, returning each bit of the scanline in
- a separate byte. We use the `line_in_bytes' variable, allocated in
- `img_get_header', to read into. */
-
- boolean
- img_get_scanline (one_byte *line_in_bits)
- {
- unsigned this_bit, this_byte, mask;
-
- if (fread (line_in_bytes, byte_width, 1, img_input_file) != 1)
- {
- if (feof (img_input_file))
- return false;
- else
- FATAL1 ("img_get_scanline: fread of %u bytes failed", byte_width);
- }
-
- for (this_bit = 0, this_byte = 0, mask = 0x80;
- this_bit < bit_width; this_bit++)
- {
- /* Somewhere along the line, black and white got reversed. */
- line_in_bits[this_bit] = (line_in_bytes[this_byte] & mask) == 0;
- if (this_bit % 8 == 0)
- {
- this_byte = this_bit / 8;
- mask = 0x80;
- }
- else
- mask >>= 1;
- }
-
- print_scanline (line_in_bits, bit_width);
-
- return true;
- }
-