first cut at PBM support.

Thu, 10 Apr 2003 08:47:30 +0000

author
eric
date
Thu, 10 Apr 2003 08:47:30 +0000
changeset 157
160d624271cc
parent 156
745483d15215
child 158
e5452e27f518

first cut at PBM support.

Makefile file | annotate | diff | revisions
tumble.c file | annotate | diff | revisions
tumble_input.h file | annotate | diff | revisions
tumble_pbm.c file | annotate | diff | revisions
     1.1 --- a/Makefile	Tue Mar 25 09:38:08 2003 +0000
     1.2 +++ b/Makefile	Thu Apr 10 08:47:30 2003 +0000
     1.3 @@ -1,6 +1,6 @@
     1.4  # tumble: build a PDF file from image files
     1.5  # Makefile
     1.6 -# $Id: Makefile,v 1.39 2003/03/25 01:38:08 eric Exp $
     1.7 +# $Id: Makefile,v 1.40 2003/04/10 00:47:30 eric Exp $
     1.8  # Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
     1.9  #
    1.10  # This program is free software; you can redistribute it and/or modify
    1.11 @@ -30,7 +30,7 @@
    1.12  
    1.13  CFLAGS = -Wall
    1.14  LDFLAGS =
    1.15 -LDLIBS = -ltiff -ljpeg -lz -lm
    1.16 +LDLIBS = -ltiff -ljpeg -lpbm -lz -lm
    1.17  
    1.18  ifdef DEBUG
    1.19  CFLAGS := $(CFLAGS) -g
    1.20 @@ -57,14 +57,14 @@
    1.21  # let me know why so I can improve this Makefile.
    1.22  # -----------------------------------------------------------------------------
    1.23  
    1.24 -VERSION = 0.32
    1.25 +VERSION = 0.33
    1.26  
    1.27  PACKAGE = tumble
    1.28  
    1.29  TARGETS = tumble
    1.30  
    1.31  CSRCS = tumble.c semantics.c \
    1.32 -	tumble_input.c tumble_tiff.c tumble_jpeg.c \
    1.33 +	tumble_input.c tumble_tiff.c tumble_jpeg.c tumble_pbm.c \
    1.34  	bitblt.c bitblt_table_gen.c bitblt_g4.c g4_table_gen.c \
    1.35  	pdf.c pdf_util.c pdf_prim.c pdf_name_tree.c \
    1.36  	pdf_bookmark.c pdf_page_label.c \
    1.37 @@ -92,7 +92,7 @@
    1.38  
    1.39  
    1.40  tumble: tumble.o semantics.o \
    1.41 -		tumble_input.o tumble_tiff.o tumble_jpeg.o \
    1.42 +		tumble_input.o tumble_tiff.o tumble_jpeg.o tumble_pbm.o \
    1.43  		scanner.o parser.tab.o \
    1.44  		bitblt.o bitblt_g4.o bitblt_tables.o g4_tables.o \
    1.45  		pdf.o pdf_util.o pdf_prim.o pdf_name_tree.o \
     2.1 --- a/tumble.c	Tue Mar 25 09:38:08 2003 +0000
     2.2 +++ b/tumble.c	Thu Apr 10 08:47:30 2003 +0000
     2.3 @@ -2,7 +2,7 @@
     2.4   * tumble: build a PDF file from image files
     2.5   *
     2.6   * Main program
     2.7 - * $Id: tumble.c,v 1.41 2003/03/20 08:23:37 eric Exp $
     2.8 + * $Id: tumble.c,v 1.42 2003/04/10 00:47:30 eric Exp $
     2.9   * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
    2.10   *
    2.11   * This program is free software; you can redistribute it and/or modify
    2.12 @@ -366,6 +366,7 @@
    2.13  
    2.14    init_tiff_handler ();
    2.15    init_jpeg_handler ();
    2.16 +  init_pbm_handler ();
    2.17  
    2.18    while (--argc)
    2.19      {
     3.1 --- a/tumble_input.h	Tue Mar 25 09:38:08 2003 +0000
     3.2 +++ b/tumble_input.h	Thu Apr 10 08:47:30 2003 +0000
     3.3 @@ -1,7 +1,7 @@
     3.4  /*
     3.5   * tumble: build a PDF file from image files
     3.6   *
     3.7 - * $Id: tumble_input.h,v 1.2 2003/03/20 06:55:27 eric Exp $
     3.8 + * $Id: tumble_input.h,v 1.3 2003/04/10 00:47:30 eric Exp $
     3.9   * Copyright 2003 Eric Smith <eric@brouhaha.com>
    3.10   *
    3.11   * This program is free software; you can redistribute it and/or modify
    3.12 @@ -64,3 +64,4 @@
    3.13  
    3.14  void init_tiff_handler (void);
    3.15  void init_jpeg_handler (void);
    3.16 +void init_pbm_handler  (void);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tumble_pbm.c	Thu Apr 10 08:47:30 2003 +0000
     4.3 @@ -0,0 +1,230 @@
     4.4 +/*
     4.5 + * tumble: build a PDF file from image files
     4.6 + *
     4.7 + * $Id: tumble_pbm.c,v 1.1 2003/04/10 00:47:30 eric Exp $
     4.8 + * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
     4.9 + *
    4.10 + * This program is free software; you can redistribute it and/or modify
    4.11 + * it under the terms of the GNU General Public License version 2 as
    4.12 + * published by the Free Software Foundation.  Note that permission is
    4.13 + * not granted to redistribute this program under the terms of any
    4.14 + * other version of the General Public License.
    4.15 + *
    4.16 + * This program is distributed in the hope that it will be useful,
    4.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.19 + * GNU General Public License for more details.
    4.20 + *
    4.21 + * You should have received a copy of the GNU General Public License
    4.22 + * along with this program; if not, write to the Free Software
    4.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
    4.24 + */
    4.25 +
    4.26 +
    4.27 +#include <stdbool.h>
    4.28 +#include <stdint.h>
    4.29 +#include <stdio.h>
    4.30 +#include <stdlib.h>
    4.31 +#include <strings.h>  /* strcasecmp() is a BSDism */
    4.32 +
    4.33 +#include <pbm.h>
    4.34 +/*
    4.35 + * pbm_readpbmrow_packed always uses big-endian bit ordering.
    4.36 + * On little-endian processors (such as the x86), we want little-endian
    4.37 + * bit order, so we must reverse the bits ourselves after we read in the
    4.38 + * file.
    4.39 + */
    4.40 +#define PBM_REVERSE_BITS
    4.41 +
    4.42 +
    4.43 +#include "semantics.h"
    4.44 +#include "tumble.h"
    4.45 +#include "bitblt.h"
    4.46 +#include "pdf.h"
    4.47 +#include "tumble_input.h"
    4.48 +
    4.49 +
    4.50 +typedef struct
    4.51 +{
    4.52 +  FILE *f;
    4.53 +  int rows;
    4.54 +  int cols;
    4.55 +  int format;
    4.56 +} pbm_info_t;
    4.57 +
    4.58 +static pbm_info_t pbm;
    4.59 +
    4.60 +
    4.61 +#define SWAP(type,a,b) do { type temp; temp = a; a = b; b = temp; } while (0)
    4.62 +
    4.63 +
    4.64 +static bool match_pbm_suffix (char *suffix)
    4.65 +{
    4.66 +  return (strcasecmp (suffix, ".pbm") == 0);
    4.67 +}
    4.68 +
    4.69 +
    4.70 +static bool close_pbm_input_file (void)
    4.71 +{
    4.72 +  pbm.f = NULL;
    4.73 +  return (1);
    4.74 +}
    4.75 +
    4.76 +
    4.77 +static bool open_pbm_input_file (FILE *f, char *name)
    4.78 +{
    4.79 +  uint8_t buf [2];
    4.80 +  size_t l;
    4.81 +
    4.82 +  l = fread (& buf [0], 1, sizeof (buf), f);
    4.83 +  if (l != sizeof (buf))
    4.84 +    return (0);
    4.85 +
    4.86 +  rewind (f);
    4.87 +
    4.88 +  if (! (((buf [0] == 'P') && (buf [1] == '1')) ||
    4.89 +	 ((buf [0] == 'P') && (buf [1] == '4'))))
    4.90 +    return (0);
    4.91 +
    4.92 +  pbm.f = f;
    4.93 +
    4.94 +  pbm_readpbminit (f, & pbm.cols, & pbm.rows, & pbm.format);
    4.95 +
    4.96 +  return (1);
    4.97 +}
    4.98 +
    4.99 +
   4.100 +static bool last_pbm_input_page (void)
   4.101 +{
   4.102 +  /* only handle single-page PBM files for now */
   4.103 +  return (1);
   4.104 +}
   4.105 +
   4.106 +
   4.107 +static bool get_pbm_image_info (int image,
   4.108 +				input_attributes_t input_attributes,
   4.109 +				image_info_t *image_info)
   4.110 +{
   4.111 +  double x_resolution = 300;
   4.112 +  double y_resolution = 300;
   4.113 +
   4.114 +  /* $$$ need to handle rotation! */
   4.115 +  if (input_attributes.has_resolution)
   4.116 +    {
   4.117 +      x_resolution = input_attributes.x_resolution;
   4.118 +      y_resolution = input_attributes.y_resolution;
   4.119 +    }
   4.120 +
   4.121 +  image_info->width_points = (pbm.cols / x_resolution) * POINTS_PER_INCH;
   4.122 +  image_info->height_points = (pbm.rows / y_resolution) * POINTS_PER_INCH;
   4.123 +
   4.124 +  if ((image_info->height_points > PAGE_MAX_POINTS) || 
   4.125 +      (image_info->width_points > PAGE_MAX_POINTS))
   4.126 +    {
   4.127 +      fprintf (stdout, "image too large (max %d inches on a side\n", PAGE_MAX_INCHES);
   4.128 +      return (0);
   4.129 +    }
   4.130 +
   4.131 +  return (1);
   4.132 +}
   4.133 +
   4.134 +
   4.135 +static bool process_pbm_image (int image,  /* range 1 .. n */
   4.136 +			       input_attributes_t input_attributes,
   4.137 +			       image_info_t *image_info,
   4.138 +			       pdf_page_handle page)
   4.139 +{
   4.140 +  bool result = 0;
   4.141 +  Rect rect;
   4.142 +  Bitmap *bitmap = NULL;
   4.143 +
   4.144 +  int row;
   4.145 +
   4.146 +  rect.min.x = 0;
   4.147 +  rect.min.y = 0;
   4.148 +
   4.149 +  if ((input_attributes.rotation == 90) || (input_attributes.rotation == 270))
   4.150 +    {
   4.151 +      rect.max.x = image_info->height_samples;
   4.152 +      rect.max.y = image_info->width_samples;
   4.153 +    }
   4.154 +  else
   4.155 +    {
   4.156 +      rect.max.x = image_info->width_samples;
   4.157 +      rect.max.y = image_info->height_samples;
   4.158 +    }
   4.159 +
   4.160 +  bitmap = create_bitmap (& rect);
   4.161 +
   4.162 +  if (! bitmap)
   4.163 +    {
   4.164 +      fprintf (stderr, "can't allocate bitmap\n");
   4.165 +      fprintf (stderr, "width %d height %d\n", image_info->width_samples, image_info->height_samples);
   4.166 +      goto fail;
   4.167 +    }
   4.168 +
   4.169 +  for (row = 0; row < rect.max.y; row++)
   4.170 +    {
   4.171 +      pbm_readpbmrow_packed (pbm.f,
   4.172 +			     (unsigned char *) (bitmap->bits + row * bitmap->row_words),
   4.173 +			     pbm.cols,
   4.174 +			     pbm.format);
   4.175 +      }
   4.176 +
   4.177 +#ifdef PBM_REVERSE_BITS
   4.178 +  reverse_bits ((uint8_t *) bitmap->bits,
   4.179 +		rect.max.y * bitmap->row_words * sizeof (word_t));
   4.180 +#endif /* PBM_REVERSE_BITS */
   4.181 +
   4.182 +  /* $$$ need to invert bits here */
   4.183 +
   4.184 +#if 0
   4.185 +  if (input_attributes.has_page_size)
   4.186 +    bitmap = resize_bitmap (bitmap,
   4.187 +			    x_resolution,
   4.188 +			    y_resolution,
   4.189 +			    input_attributes);
   4.190 +#endif
   4.191 +
   4.192 +#if 0
   4.193 +  rotate_bitmap (bitmap,
   4.194 +		 input_attributes);
   4.195 +#endif
   4.196 +
   4.197 +  pdf_write_g4_fax_image (page,
   4.198 +			  0, 0,  /* x, y */
   4.199 +			  image_info->width_points, image_info->height_points,
   4.200 +			  bitmap,
   4.201 +			  0, /* ImageMask */
   4.202 +			  0, 0, 0,  /* r, g, b */
   4.203 +			  0); /* BlackIs1 */
   4.204 +
   4.205 +  result = 1;
   4.206 +
   4.207 + fail:
   4.208 +  if (bitmap)
   4.209 +    free_bitmap (bitmap);
   4.210 +  return (result);
   4.211 +}
   4.212 +
   4.213 +
   4.214 +input_handler_t pbm_handler =
   4.215 +  {
   4.216 +    match_pbm_suffix,
   4.217 +    open_pbm_input_file,
   4.218 +    close_pbm_input_file,
   4.219 +    last_pbm_input_page,
   4.220 +    get_pbm_image_info,
   4.221 +    process_pbm_image
   4.222 +  };
   4.223 +
   4.224 +
   4.225 +void init_pbm_handler (void)
   4.226 +{
   4.227 +  /* why should we let libpbm look at the real args? */
   4.228 +  int fake_argc = 1;
   4.229 +  char *fake_argv [] = { "tumble" };
   4.230 +
   4.231 +  pbm_init (& fake_argc, fake_argv);
   4.232 +  install_input_handler (& pbm_handler);
   4.233 +}