Thu, 20 Feb 2003 12:44:17 +0000
my own PDF routines to replace Panda.
1 /*
2 * t2p: Create a PDF file from the contents of one or more TIFF
3 * bilevel image files. The images in the resulting PDF file
4 * will be compressed using ITU-T T.6 (G4) fax encoding.
5 *
6 * PDF routines
7 * $Id: bitblt_g4.c,v 1.3 2003/02/20 04:44:17 eric Exp $
8 * Copyright 2001, 2002, 2003 Eric Smith <eric@brouhaha.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. Note that permission is
13 * not granted to redistribute this program under the terms of any
14 * other version of the General Public License.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
24 */
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <string.h>
33 #include "bitblt.h"
34 #include "pdf.h"
35 #include "pdf_util.h"
36 #include "pdf_prim.h"
37 #include "pdf_private.h"
40 struct pdf_g4_image
41 {
42 unsigned long Columns;
43 unsigned long Rows;
44 int BlackIs1;
45 Bitmap *bitmap;
46 char XObject_name [4];
47 };
50 char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref)
51 {
52 char XObject_name [4] = "Im ";
54 XObject_name [2] = ++pdf_page->last_XObject_name;
56 if (! pdf_page->XObject_dict)
57 {
58 pdf_page->XObject_dict = pdf_new_obj (PT_DICTIONARY);
59 pdf_set_dict_entry (pdf_page->resources, "XObject", pdf_page->XObject_dict);
60 }
62 pdf_set_dict_entry (pdf_page->XObject_dict, & XObject_name [0], ind_ref);
64 return (pdf_page->last_XObject_name);
65 }
68 void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
69 struct pdf_obj *stream,
70 void *app_data)
71 {
72 unsigned long width = (8.5 * 72); /* full width of page */
73 unsigned long height = (11 * 72); /* full height of page */
74 unsigned long x = 0; /* 0 is left edge */
75 unsigned long y = 0; /* 0 is bottom edge */
76 struct pdf_g4_image *image = app_data;
78 char str1 [100];
79 char *str2 = "/";
80 char *str3 = " Do\r\n";
82 /* width 0 0 height x y cm */
83 sprintf (str1, "q %ld 0 0 %ld %ld %ld cm\r\n", width, height, x, y);
85 pdf_stream_write_data (pdf_file, stream, str1, strlen (str1));
86 pdf_stream_write_data (pdf_file, stream, str2, strlen (str2));
87 pdf_stream_write_data (pdf_file, stream, & image->XObject_name [0],
88 strlen (& image->XObject_name [0]));
89 pdf_stream_write_data (pdf_file, stream, str3, strlen (str3));
90 }
93 void pdf_write_g4_fax_image_callback (pdf_file_handle pdf_file,
94 struct pdf_obj *stream,
95 void *app_data)
96 {
97 struct pdf_g4_image *image = app_data;
99 #if 0
100 pdf_stream_write_data (pdf_file, stream, image->data, image->len);
101 #else
102 unsigned long row = 0;
103 word_type *ref;
104 word_type *raw;
106 ref = NULL;
107 raw = image->bitmap->bits;
109 while (row < image->Rows)
110 {
111 pdf_stream_write_data (pdf_file, stream, raw,
112 image->bitmap->row_words * sizeof (word_type));
114 row++;
115 ref = raw;
116 raw += image->bitmap->row_words;
117 }
118 /* $$$ generate and write EOFB code */
119 /* $$$ flush any remaining buffered bits */
120 #endif
121 }
124 void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
125 Bitmap *bitmap,
126 int ImageMask,
127 int BlackIs1) /* boolean, typ. false */
128 {
129 struct pdf_g4_image *image;
131 struct pdf_obj *stream;
132 struct pdf_obj *stream_dict;
133 struct pdf_obj *decode_parms;
135 struct pdf_obj *content_stream;
137 image = pdf_calloc (sizeof (struct pdf_g4_image));
139 image->bitmap = bitmap;
140 image->Columns = bitmap->rect.max.x - bitmap->rect.min.x;
141 image->Rows = bitmap->rect.max.y - bitmap->rect.min.y;
142 image->BlackIs1 = BlackIs1;
144 stream_dict = pdf_new_obj (PT_DICTIONARY);
146 stream = pdf_new_ind_ref (pdf_page->pdf_file,
147 pdf_new_stream (pdf_page->pdf_file,
148 stream_dict,
149 & pdf_write_g4_fax_image_callback,
150 image));
152 strcpy (& image->XObject_name [0], "Im ");
153 image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
155 pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject"));
156 pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
157 pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0]));
158 pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->Columns));
159 pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->Rows));
160 pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
161 if (ImageMask)
162 pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
163 else
164 pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
166 decode_parms = pdf_new_obj (PT_DICTIONARY);
168 pdf_set_dict_entry (decode_parms,
169 "K",
170 pdf_new_integer (-1));
172 pdf_set_dict_entry (decode_parms,
173 "Columns",
174 pdf_new_integer (image->Columns));
176 pdf_set_dict_entry (decode_parms,
177 "Rows",
178 pdf_new_integer (image->Rows));
180 if (BlackIs1)
181 pdf_set_dict_entry (decode_parms,
182 "BlackIs1",
183 pdf_new_bool (BlackIs1));
185 pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
187 /* the following will write the stream, using our callback function to
188 get the actual data */
189 pdf_write_ind_obj (pdf_page->pdf_file, stream);
191 content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
192 pdf_new_stream (pdf_page->pdf_file,
193 pdf_new_obj (PT_DICTIONARY),
194 & pdf_write_g4_content_callback,
195 image));
197 pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
199 pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
200 }