Thu, 20 Mar 2003 07:06:35 +0000
*** empty log message ***
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 }