home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / fontutils-0.6 / gsrenderfont / input-pbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-23  |  4.7 KB  |  173 lines

  1. /* input-pbm.c: read a PBM file.
  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 "bitmap.h"
  22. #include "file-input.h"
  23. #include "pbm.h"
  24.  
  25. /* From main.c.  */
  26. extern int debug;
  27. extern boolean trace_scanlines;
  28.  
  29. /* Where the input comes from.  */
  30. static FILE *pbm_input_file;
  31. static string pbm_input_filename;
  32.  
  33. static void get_row (one_byte *, int, int);
  34.  
  35. /* Only one file can be open at a time.  We do no path searching.  If
  36.    FILENAME can't be opened, we quit.  */
  37.  
  38. void
  39. pbm_open_input_file (string filename)
  40. {
  41.   assert (pbm_input_file == NULL);
  42.   
  43.   pbm_input_file = xfopen (filename, "r");
  44.   pbm_input_filename = filename;
  45. }
  46.  
  47.  
  48. /* Close the input file.  If it hasn't been opened, we quit.  */
  49.  
  50. void
  51. pbm_close_input_file ()
  52. {
  53.   assert (pbm_input_file != NULL);
  54.   
  55.   xfclose (pbm_input_file, pbm_input_filename);
  56.   pbm_input_file = NULL;
  57. }
  58.  
  59. /* Read a block exactly HEIGHT scanlines high from the image.  The last
  60.    few scanlines must all be blank (we don't bother to return them).  If
  61.    they aren't, then something is wrong.  A rounding error has caused
  62.    Ghostscript to give us fewer lines than expected.  Just return a
  63.    short block, and save the first nonblank line (we don't read past the
  64.    first) for next time.  */
  65.  
  66. /* The constant here must match that in writefont.PS's calculation of
  67.    max-char-tall-in-pixels.  */
  68. #define BLANK_COUNT 4
  69.  
  70. bitmap_type *
  71. pbm_get_block (unsigned height)
  72. {
  73.   static int image_width = -1;
  74.   static one_byte *saved_scanline = NULL;
  75.   static one_byte *blank_row;
  76.   static int image_format;
  77.   static int image_height;
  78.   int c;
  79.   one_byte *row;
  80.   one_byte *block;
  81.   unsigned block_height, blank;
  82.   bitmap_type *b = XTALLOC1 (bitmap_type);
  83.  
  84.   /* Initialize the PBM info if necessary.  */
  85.   if (image_width == -1)
  86.     {
  87.       pbm_readpbminit (pbm_input_file, &image_width, &image_height,
  88.                        &image_format);
  89.       blank_row = xmalloc (image_width);
  90.     }
  91.  
  92.  
  93.   /* If we have a saved scanline, let that start us off.  */
  94.   block = saved_scanline;
  95.   block_height = !!block;
  96.  
  97.   /* Attach rows until we get to an all-white row that is after row #
  98.      `height - BLANK_COUNT'.  */
  99.   do
  100.     {
  101.       /* If we're at the end of the file, quit.  Presumably there was
  102.          one last blank row at the end or something.  If something was
  103.          seriously wrong, it'll manifest itself later.  */
  104.       c = getc (pbm_input_file);
  105.       if (c == EOF)
  106.         return NULL;
  107.       ungetc (c, pbm_input_file);
  108.  
  109.       block_height++;
  110.       block = xrealloc (block, block_height * image_width);
  111.       row = block + (block_height - 1) * image_width;
  112.       get_row (row, image_width, image_format);
  113.     }
  114.   while (block_height <= height - BLANK_COUNT
  115.          || memchr (row, BLACK, image_width));
  116.  
  117.   /* Skip the next BLANK_COUNT rows (they had better be blank).  We can
  118.      keep using `row' as our buffer, since it just points to the
  119.      all-blank row we found; we won't be including it in the bitmap we
  120.      return.  We might hit the end of the image here, in which case we
  121.      just stop.  */
  122.   for (blank = 1; blank < BLANK_COUNT; blank++)
  123.     {
  124.       c = getc (pbm_input_file);
  125.       if (c == EOF)
  126.         break;
  127.         
  128.       ungetc (c, pbm_input_file);
  129.       get_row (blank_row, image_width, image_format);
  130.  
  131.       if (memchr (blank_row, BLACK, image_width) != NULL)
  132.         break;
  133.     }
  134.  
  135.   if (blank == BLANK_COUNT)
  136.     saved_scanline = NULL;
  137.   else
  138.     {
  139.       saved_scanline = xmalloc (image_width);
  140.       memcpy (saved_scanline, blank_row, image_width);
  141.     }
  142.   
  143.   /* Fill in the bitmap to return.  */
  144.   BITMAP_WIDTH (*b) = image_width;
  145.   BITMAP_HEIGHT (*b) = block_height;
  146.   BITMAP_BITS (*b) = block;
  147.  
  148.   if (debug) print_bitmap (stdout, *b);
  149.  
  150.   return b;
  151. }
  152.  
  153.  
  154. /* Read a single row from the image.  */
  155.  
  156. static void
  157. get_row (one_byte *row, int width, int format)
  158. {
  159.   static unsigned scanline_count = 0;
  160.  
  161.   pbm_readpbmrow (pbm_input_file, row, width, format);
  162.   scanline_count++;
  163.  
  164.   if (trace_scanlines)
  165.     {
  166.       int c;
  167.       printf ("%5d:", scanline_count);
  168.       for (c = 0; c < width; c++)
  169.         putchar (row[c] ? '*' : ' ');
  170.       putchar ('\n');
  171.     }
  172. }
  173.