tumble_jpeg.c

Thu, 20 Mar 2003 06:54:08 +0000

author
eric
date
Thu, 20 Mar 2003 06:54:08 +0000
changeset 141
752599b50ff3
child 147
090af3709920
permissions
-rw-r--r--

more JPEG support. added input file handler API.

     1 /*
     2  * tumble: build a PDF file from image files
     3  *
     4  * $Id: tumble_jpeg.c,v 1.1 2003/03/19 22:54:08 eric Exp $
     5  * Copyright 2003 Eric Smith <eric@brouhaha.com>
     6  *
     7  * This program is free software; you can redistribute it and/or modify
     8  * it under the terms of the GNU General Public License version 2 as
     9  * published by the Free Software Foundation.  Note that permission is
    10  * not granted to redistribute this program under the terms of any
    11  * other version of the General Public License.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
    21  */
    24 #include <stdbool.h>
    25 #include <stdint.h>
    26 #include <stdio.h>
    27 #include <jpeglib.h>
    30 #include "semantics.h"
    31 #include "tumble.h"
    32 #include "bitblt.h"
    33 #include "pdf.h"
    34 #include "tumble_input.h"
    37 static FILE *jpeg_f;
    39 static struct jpeg_decompress_struct cinfo;
    40 static struct jpeg_error_mgr jerr;
    43 bool close_jpeg_input_file (void)
    44 {
    45   return (1);
    46 }
    49 bool open_jpeg_input_file (FILE *f, char *name)
    50 {
    51   uint8_t buf [2];
    52   size_t l;
    54   l = fread (& buf [0], 1, sizeof (buf), f);
    55   if (l != sizeof (buf))
    56     return (0);
    58   rewind (f);
    60   if ((buf [0] != 0xff) || (buf [1] != 0xd8))
    61     return (0);
    63   cinfo.err = jpeg_std_error (& jerr);
    64   jpeg_create_decompress (& cinfo);
    66   jpeg_stdio_src (& cinfo, f);
    68   jpeg_read_header (& cinfo, TRUE);
    70   rewind (f);
    72   jpeg_f = f;
    74   return (1);
    75 }
    78 bool last_jpeg_input_page (void)
    79 {
    80   return (1);
    81 }
    84 bool get_jpeg_image_info (int image,
    85 			  input_attributes_t input_attributes,
    86 			  image_info_t *image_info)
    87 {
    88   double unit;
    90   switch (cinfo.jpeg_color_space)
    91     {
    92     case JCS_GRAYSCALE:
    93       if (cinfo.num_components != 1)
    94 	{
    95 	  fprintf (stderr, "JPEG grayscale image has %d components, should have 1\n",
    96 		   cinfo.num_components);
    97 	  return (0);
    98 	}
    99       image_info->color = 0;
   100       break;
   101     case JCS_RGB:
   102     case JCS_YCbCr:
   103       if (cinfo.num_components != 3)
   104 	{
   105 	  fprintf (stderr, "JPEG RGB or YCbCr image has %d components, should have 3\n",
   106 		   cinfo.num_components);
   107 	  return (0);
   108 	}
   109       image_info->color = 1;
   110       break;
   111     default:
   112       fprintf (stderr, "JPEG color space %d not supported\n", cinfo.jpeg_color_space);
   113       return (0);
   114     }
   115   image_info->width_samples = cinfo.image_width;
   116   image_info->height_samples = cinfo.image_height;
   118   if (cinfo.saw_JFIF_marker & cinfo.density_unit)
   119     {
   120       switch (cinfo.density_unit)
   121 	{
   122 	case 1:  /* samples per inch */
   123 	  unit = 1.0;
   124 	  break;
   125 	case 2:  /* samples per cm */
   126 	  unit = 2.54;
   127 	  break;
   128 	default:
   129 	  fprintf (stderr, "JFIF density unit %d not supported\n", cinfo.density_unit);
   130 	  return (0);
   131 	}
   132       image_info->width_points = ((image_info->width_samples * POINTS_PER_INCH) /
   133 				  (cinfo.X_density * unit));
   134       image_info->height_points = ((image_info->height_samples * POINTS_PER_INCH) /
   135 				   (cinfo.Y_density * unit));
   136     }
   137   else
   138     {
   139       /* assume 300 DPI - not great, but what else can we do? */
   140       image_info->width_points = (image_info->width_samples * POINTS_PER_INCH) / 300.0;
   141       image_info->height_points = (image_info->height_samples * POINTS_PER_INCH) / 300.0;
   142     }
   144   return (1);
   145 }
   148 bool process_jpeg_image (int image,  /* range 1 .. n */
   149 			 input_attributes_t input_attributes,
   150 			 image_info_t *image_info,
   151 			 pdf_page_handle page)
   152 {
   153   pdf_write_jpeg_image (page,
   154 			0, 0,  /* x, y */
   155 			image_info->width_points,
   156 			image_info->height_points,
   157 			jpeg_f);
   159   return (page);
   160 }
   163 input_handler_t jpeg_handler =
   164   {
   165     open_jpeg_input_file,
   166     close_jpeg_input_file,
   167     last_jpeg_input_page,
   168     get_jpeg_image_info,
   169     process_jpeg_image
   170   };
   173 void init_jpeg_handler (void)
   174 {
   175   install_input_handler (& jpeg_handler);
   176 }