tumble_jpeg.c

Mon, 14 Dec 2009 16:17:02 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 14 Dec 2009 16:17:02 +0000
changeset 170
e375cda0342e
parent 151
83a99cc69861
permissions
-rw-r--r--

change VERSION to 0.33-philpem1

eric@141 1 /*
eric@141 2 * tumble: build a PDF file from image files
eric@141 3 *
eric@151 4 * $Id: tumble_jpeg.c,v 1.4 2003/03/20 06:55:27 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@151 27 #include <strings.h> /* strcasecmp() is a BSDism */
eric@141 28 #include <jpeglib.h>
eric@141 29
eric@141 30
eric@141 31 #include "semantics.h"
eric@141 32 #include "tumble.h"
eric@141 33 #include "bitblt.h"
eric@141 34 #include "pdf.h"
eric@141 35 #include "tumble_input.h"
eric@141 36
eric@141 37
eric@141 38 static FILE *jpeg_f;
eric@141 39
eric@141 40 static struct jpeg_decompress_struct cinfo;
eric@141 41 static struct jpeg_error_mgr jerr;
eric@141 42
eric@141 43
eric@151 44 static bool match_jpeg_suffix (char *suffix)
eric@151 45 {
eric@151 46 return ((strcasecmp (suffix, ".jpg") == 0) ||
eric@151 47 (strcasecmp (suffix, ".jpeg") == 0));
eric@151 48 }
eric@151 49
eric@151 50 static bool close_jpeg_input_file (void)
eric@141 51 {
eric@141 52 return (1);
eric@141 53 }
eric@141 54
eric@141 55
eric@151 56 static bool open_jpeg_input_file (FILE *f, char *name)
eric@141 57 {
eric@141 58 uint8_t buf [2];
eric@141 59 size_t l;
eric@141 60
eric@141 61 l = fread (& buf [0], 1, sizeof (buf), f);
eric@141 62 if (l != sizeof (buf))
eric@141 63 return (0);
eric@141 64
eric@141 65 rewind (f);
eric@141 66
eric@141 67 if ((buf [0] != 0xff) || (buf [1] != 0xd8))
eric@141 68 return (0);
eric@141 69
eric@141 70 cinfo.err = jpeg_std_error (& jerr);
eric@141 71 jpeg_create_decompress (& cinfo);
eric@141 72
eric@141 73 jpeg_stdio_src (& cinfo, f);
eric@141 74
eric@141 75 jpeg_read_header (& cinfo, TRUE);
eric@141 76
eric@141 77 rewind (f);
eric@141 78
eric@141 79 jpeg_f = f;
eric@141 80
eric@141 81 return (1);
eric@141 82 }
eric@141 83
eric@141 84
eric@151 85 static bool last_jpeg_input_page (void)
eric@141 86 {
eric@141 87 return (1);
eric@141 88 }
eric@141 89
eric@141 90
eric@151 91 static bool get_jpeg_image_info (int image,
eric@151 92 input_attributes_t input_attributes,
eric@151 93 image_info_t *image_info)
eric@141 94 {
eric@141 95 double unit;
eric@141 96
eric@147 97 #ifdef DEBUG_JPEG
eric@147 98 printf ("color space: %d\n", cinfo.jpeg_color_space);
eric@147 99 printf ("components: %d\n", cinfo.num_components);
eric@147 100 printf ("density unit: %d\n", cinfo.density_unit);
eric@147 101 printf ("x density: %d\n", cinfo.X_density);
eric@147 102 printf ("y density: %d\n", cinfo.Y_density);
eric@147 103 printf ("width: %d\n", cinfo.image_width);
eric@147 104 printf ("height: %d\n", cinfo.image_height);
eric@147 105 #endif
eric@147 106
eric@141 107 switch (cinfo.jpeg_color_space)
eric@141 108 {
eric@141 109 case JCS_GRAYSCALE:
eric@141 110 if (cinfo.num_components != 1)
eric@141 111 {
eric@141 112 fprintf (stderr, "JPEG grayscale image has %d components, should have 1\n",
eric@141 113 cinfo.num_components);
eric@141 114 return (0);
eric@141 115 }
eric@141 116 image_info->color = 0;
eric@141 117 break;
eric@141 118 case JCS_RGB:
eric@141 119 case JCS_YCbCr:
eric@141 120 if (cinfo.num_components != 3)
eric@141 121 {
eric@141 122 fprintf (stderr, "JPEG RGB or YCbCr image has %d components, should have 3\n",
eric@141 123 cinfo.num_components);
eric@141 124 return (0);
eric@141 125 }
eric@141 126 image_info->color = 1;
eric@141 127 break;
eric@141 128 default:
eric@141 129 fprintf (stderr, "JPEG color space %d not supported\n", cinfo.jpeg_color_space);
eric@141 130 return (0);
eric@141 131 }
eric@141 132 image_info->width_samples = cinfo.image_width;
eric@141 133 image_info->height_samples = cinfo.image_height;
eric@141 134
eric@141 135 if (cinfo.saw_JFIF_marker & cinfo.density_unit)
eric@141 136 {
eric@141 137 switch (cinfo.density_unit)
eric@141 138 {
eric@141 139 case 1: /* samples per inch */
eric@141 140 unit = 1.0;
eric@141 141 break;
eric@141 142 case 2: /* samples per cm */
eric@141 143 unit = 2.54;
eric@141 144 break;
eric@141 145 default:
eric@141 146 fprintf (stderr, "JFIF density unit %d not supported\n", cinfo.density_unit);
eric@141 147 return (0);
eric@141 148 }
eric@141 149 image_info->width_points = ((image_info->width_samples * POINTS_PER_INCH) /
eric@141 150 (cinfo.X_density * unit));
eric@141 151 image_info->height_points = ((image_info->height_samples * POINTS_PER_INCH) /
eric@141 152 (cinfo.Y_density * unit));
eric@141 153 }
eric@141 154 else
eric@141 155 {
eric@141 156 /* assume 300 DPI - not great, but what else can we do? */
eric@141 157 image_info->width_points = (image_info->width_samples * POINTS_PER_INCH) / 300.0;
eric@141 158 image_info->height_points = (image_info->height_samples * POINTS_PER_INCH) / 300.0;
eric@141 159 }
eric@141 160
eric@141 161 return (1);
eric@141 162 }
eric@141 163
eric@141 164
eric@151 165 static bool process_jpeg_image (int image, /* range 1 .. n */
eric@151 166 input_attributes_t input_attributes,
eric@151 167 image_info_t *image_info,
eric@151 168 pdf_page_handle page)
eric@141 169 {
eric@141 170 pdf_write_jpeg_image (page,
eric@141 171 0, 0, /* x, y */
eric@141 172 image_info->width_points,
eric@141 173 image_info->height_points,
eric@147 174 image_info->color,
eric@147 175 image_info->width_samples,
eric@147 176 image_info->height_samples,
eric@141 177 jpeg_f);
eric@141 178
eric@150 179 return (1);
eric@141 180 }
eric@141 181
eric@141 182
eric@141 183 input_handler_t jpeg_handler =
eric@141 184 {
eric@151 185 match_jpeg_suffix,
eric@141 186 open_jpeg_input_file,
eric@141 187 close_jpeg_input_file,
eric@141 188 last_jpeg_input_page,
eric@141 189 get_jpeg_image_info,
eric@141 190 process_jpeg_image
eric@141 191 };
eric@141 192
eric@141 193
eric@141 194 void init_jpeg_handler (void)
eric@141 195 {
eric@141 196 install_input_handler (& jpeg_handler);
eric@141 197 }