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.

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