tioga 1.11 → 1.13
Sign up to get free protection for your applications and to get access to all the features.
- data/Tioga_README +58 -35
- data/{split/scripts → bin}/tioga +1 -1
- data/{split → ext/Dobjects}/Dtable/dtable.c +81 -15
- data/{split → ext/Dobjects}/Dtable/dtable_intern.h +0 -0
- data/ext/Dobjects/Dtable/extconf.rb +7 -0
- data/{split → ext/Dobjects}/Dtable/include/dtable.h +0 -0
- data/{split → ext/Dobjects}/Dvector/dvector.c +361 -51
- data/{split → ext/Dobjects}/Dvector/dvector_intern.h +0 -0
- data/ext/Dobjects/Dvector/extconf.rb +22 -0
- data/{split/Dtable → ext/Dobjects/Dvector/include}/dvector.h +0 -0
- data/ext/Dobjects/Function/extconf.rb +7 -0
- data/{split → ext/Dobjects}/Function/function.c +636 -11
- data/{split → ext/Dobjects}/Function/joint_qsort.c +0 -0
- data/ext/Flate/extconf.rb +26 -0
- data/{split → ext}/Flate/flate.c +7 -3
- data/{split → ext}/Flate/flate_intern.h +0 -0
- data/{split → ext}/Flate/include/flate.h +0 -0
- data/ext/Flate/zlib/adler32.c +149 -0
- data/ext/Flate/zlib/compress.c +79 -0
- data/ext/Flate/zlib/crc32.c +423 -0
- data/ext/Flate/zlib/crc32.h +441 -0
- data/ext/Flate/zlib/deflate.c +1736 -0
- data/ext/Flate/zlib/deflate.h +331 -0
- data/ext/Flate/zlib/gzio.c +1026 -0
- data/ext/Flate/zlib/infback.c +623 -0
- data/ext/Flate/zlib/inffast.c +318 -0
- data/ext/Flate/zlib/inffast.h +11 -0
- data/ext/Flate/zlib/inffixed.h +94 -0
- data/ext/Flate/zlib/inflate.c +1368 -0
- data/ext/Flate/zlib/inflate.h +115 -0
- data/ext/Flate/zlib/inftrees.c +329 -0
- data/ext/Flate/zlib/inftrees.h +55 -0
- data/ext/Flate/zlib/trees.c +1219 -0
- data/ext/Flate/zlib/trees.h +128 -0
- data/ext/Flate/zlib/uncompr.c +61 -0
- data/ext/Flate/zlib/zlib.h +1357 -0
- data/ext/Flate/zlib/zutil.c +318 -0
- data/ext/Flate/zlib/zutil.h +269 -0
- data/ext/Tioga/FigureMaker/__shared_axes.c +1373 -0
- data/ext/Tioga/FigureMaker/__shared_makers.c +1303 -0
- data/{split/Tioga/pdf_font_dicts.c → ext/Tioga/FigureMaker/__shared_pdf_font_dicts.c} +0 -0
- data/{split/Tioga/pdfcolor.c → ext/Tioga/FigureMaker/__shared_pdfcolor.c} +0 -0
- data/{split/Tioga/pdfcoords.c → ext/Tioga/FigureMaker/__shared_pdfcoords.c} +0 -0
- data/{split/Tioga/pdffile.c → ext/Tioga/FigureMaker/__shared_pdffile.c} +0 -0
- data/{split/Tioga/pdfimage.c → ext/Tioga/FigureMaker/__shared_pdfimage.c} +0 -0
- data/{split/Tioga/pdfpath.c → ext/Tioga/FigureMaker/__shared_pdfpath.c} +0 -0
- data/{split/Tioga/pdftext.c → ext/Tioga/FigureMaker/__shared_pdftext.c} +0 -0
- data/{split/Tioga/texout.c → ext/Tioga/FigureMaker/__shared_texout.c} +0 -0
- data/ext/Tioga/FigureMaker/extconf.rb +7 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/figures.c +14 -2
- data/{split/Tioga → ext/Tioga/FigureMaker}/figures.h +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/generic.c +1 -2
- data/{split/Tioga → ext/Tioga/FigureMaker}/generic.h +0 -1
- data/{split/Tioga → ext/Tioga/FigureMaker}/init.c +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/pdfs.h +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker/shared}/axes.c +32 -7
- data/{split/Tioga → ext/Tioga/FigureMaker/shared}/makers.c +2 -2
- data/ext/Tioga/FigureMaker/shared/pdf_font_dicts.c +18253 -0
- data/ext/Tioga/FigureMaker/shared/pdfcolor.c +904 -0
- data/ext/Tioga/FigureMaker/shared/pdfcoords.c +518 -0
- data/ext/Tioga/FigureMaker/shared/pdffile.c +451 -0
- data/ext/Tioga/FigureMaker/shared/pdfimage.c +539 -0
- data/ext/Tioga/FigureMaker/shared/pdfpath.c +766 -0
- data/ext/Tioga/FigureMaker/shared/pdftext.c +710 -0
- data/ext/Tioga/FigureMaker/shared/texout.c +533 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.c +5 -5
- data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.h +0 -0
- data/{split/Dtable → ext/includes}/defs.h +0 -0
- data/{split/Dtable → ext/includes}/namespace.h +0 -0
- data/{split/Dtable → ext/includes}/safe_double.h +0 -0
- data/{split → ext/includes}/symbols.c +0 -1
- data/{split/Dtable → ext/includes}/symbols.h +0 -0
- data/{split/Dtable/lib → lib/Dobjects}/Dtable_extras.rb +0 -0
- data/{split/Dvector/lib → lib/Dobjects}/Dvector_extras.rb +1 -0
- data/{split/Function/lib → lib/Dobjects}/Function_extras.rb +0 -0
- data/{split/Dvector/lib → lib/Dobjects}/Numeric_extras.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Arcs_and_Circles.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/ColorConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Colorbars.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Colormaps.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Coordinate_Conversions.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Creating_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Doc.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Executive.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/FigMkr.rb +13 -70
- data/{split/Tioga/lib → lib/Tioga}/FigureConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Figures_and_Plots.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Images.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Legends.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/MarkerConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Markers.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Page_Frame_Bounds.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Rectangles.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Shading.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Special_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Strokes.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/TeX_Text.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/TexPreamble.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Titles_and_Labels.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Transparency.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Using_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Utils.rb +74 -0
- data/{split/Tioga/lib → lib/Tioga}/X_and_Y_Axes.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/irb_tioga.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/maker.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga_ui.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga_ui_cmds.rb +0 -0
- data/tests/Icon_Test.pdf +0 -0
- data/tests/benchmark_dvector_reads.rb +20 -42
- data/tests/tc_Dvector.rb +45 -4
- data/tests/tc_Flate.rb +4 -5
- data/tests/tc_Function.rb +79 -0
- data/tests/vg.log +1453 -0
- metadata +141 -122
- data/split/Dtable/extconf.rb +0 -4
- data/split/Dvector/defs.h +0 -39
- data/split/Dvector/extconf.rb +0 -4
- data/split/Dvector/include/dvector.h +0 -77
- data/split/Dvector/namespace.h +0 -59
- data/split/Dvector/safe_double.h +0 -104
- data/split/Dvector/symbols.h +0 -52
- data/split/Flate/defs.h +0 -39
- data/split/Flate/extconf.rb +0 -19
- data/split/Flate/namespace.h +0 -59
- data/split/Flate/safe_double.h +0 -104
- data/split/Flate/symbols.h +0 -52
- data/split/Function/defs.h +0 -39
- data/split/Function/dvector.h +0 -77
- data/split/Function/extconf.rb +0 -4
- data/split/Function/namespace.h +0 -59
- data/split/Function/safe_double.h +0 -104
- data/split/Function/symbols.h +0 -52
- data/split/Tioga/defs.h +0 -39
- data/split/Tioga/dtable.h +0 -35
- data/split/Tioga/dvector.h +0 -77
- data/split/Tioga/extconf.rb +0 -4
- data/split/Tioga/flate.h +0 -98
- data/split/Tioga/mk_tioga_sty.rb +0 -53
- data/split/Tioga/namespace.h +0 -59
- data/split/Tioga/safe_double.h +0 -104
- data/split/Tioga/symbols.h +0 -52
- data/split/defs.h +0 -39
- data/split/extconf.rb +0 -125
- data/split/mkmf2.rb +0 -1623
- data/split/namespace.h +0 -59
- data/split/safe_double.h +0 -104
- data/split/symbols.h +0 -52
@@ -0,0 +1,451 @@
|
|
1
|
+
/* pdffile.c */
|
2
|
+
/*
|
3
|
+
Copyright (C) 2005 Bill Paxton
|
4
|
+
|
5
|
+
This file is part of Tioga.
|
6
|
+
|
7
|
+
Tioga is free software; you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU General Library Public License as published
|
9
|
+
by the Free Software Foundation; either version 2 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
Tioga is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Library General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Library General Public License
|
18
|
+
along with Tioga; if not, write to the Free Software
|
19
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <time.h>
|
23
|
+
#include "figures.h"
|
24
|
+
#include "pdfs.h"
|
25
|
+
|
26
|
+
#define FLATE_ENCODE 1
|
27
|
+
|
28
|
+
#define Get_pdf_xoffset() 5.0
|
29
|
+
#define Get_pdf_yoffset() 5.0
|
30
|
+
|
31
|
+
|
32
|
+
/* must match the font numbers in FigureConstants.rb */
|
33
|
+
char *predefined_Fonts[] = {
|
34
|
+
NULL,
|
35
|
+
"Times-Roman",
|
36
|
+
"Times-Italic", // 2
|
37
|
+
"Times-Bold",
|
38
|
+
"Times-BoldItalic",
|
39
|
+
"Helvetica",
|
40
|
+
"Helvetica-Oblique", // 6
|
41
|
+
"Helvetica-Bold",
|
42
|
+
"Helvetica-BoldOblique",
|
43
|
+
"Courier",
|
44
|
+
"Courier-Oblique", // 10
|
45
|
+
"Courier-Bold",
|
46
|
+
"Courier-BoldOblique",
|
47
|
+
"Symbol",
|
48
|
+
"ZapfDingbats" // 14
|
49
|
+
};
|
50
|
+
int num_predefined_fonts = 14;
|
51
|
+
int num_pdf_standard_fonts = 14;
|
52
|
+
|
53
|
+
long *obj_offsets, capacity_obj_offsets, stream_start, stream_end;
|
54
|
+
long length_offset, xref_offset;
|
55
|
+
long num_objects, next_available_object_number, next_available_gs_number;
|
56
|
+
long next_available_xo_number;
|
57
|
+
long next_available_shade_number, next_available_font_number;
|
58
|
+
Stroke_Opacity_State *stroke_opacities = NULL;
|
59
|
+
Fill_Opacity_State *fill_opacities = NULL;
|
60
|
+
XObject_Info *xobj_list = NULL;
|
61
|
+
Function_Info *functions_list;
|
62
|
+
Shading_Info *shades_list = NULL;
|
63
|
+
Font_Dictionary *font_dictionaries = NULL;
|
64
|
+
Old_Font_Dictionary *old_font_dictionaries = NULL;
|
65
|
+
FILE *OF = NULL; // for the PDF file
|
66
|
+
FILE *TF = NULL; // for the temp file
|
67
|
+
|
68
|
+
|
69
|
+
/* PDF File Management */
|
70
|
+
|
71
|
+
static void
|
72
|
+
Free_XObjects(int *ierr)
|
73
|
+
{
|
74
|
+
XObject_Info *xo;
|
75
|
+
while (xobj_list != NULL) {
|
76
|
+
xo = xobj_list;
|
77
|
+
xobj_list = xo->next;
|
78
|
+
switch (xo->xobj_subtype) {
|
79
|
+
case JPG_SUBTYPE:
|
80
|
+
Free_JPG((JPG_Info *)xo);
|
81
|
+
break;
|
82
|
+
case SAMPLED_SUBTYPE:
|
83
|
+
Free_Sampled((Sampled_Info *)xo);
|
84
|
+
break;
|
85
|
+
default:
|
86
|
+
RAISE_ERROR_i("Invalid XObject subtype (%i)",
|
87
|
+
xo->xobj_subtype, ierr);
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
free(xo);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
void
|
96
|
+
Init_pdf(int *ierr)
|
97
|
+
{
|
98
|
+
int i;
|
99
|
+
writing_file = false;
|
100
|
+
capacity_obj_offsets = 1000;
|
101
|
+
num_objects = 0;
|
102
|
+
obj_offsets = ALLOC_N_long(capacity_obj_offsets);
|
103
|
+
for (i=0; i < capacity_obj_offsets; i++) obj_offsets[i] = 0;
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
void
|
108
|
+
Record_Object_Offset(int obj_number)
|
109
|
+
{
|
110
|
+
long int offset = ftell(OF);
|
111
|
+
if (obj_number >= capacity_obj_offsets) {
|
112
|
+
int size_increment = 50, i;
|
113
|
+
REALLOC_long(&obj_offsets, obj_number + size_increment);
|
114
|
+
capacity_obj_offsets = obj_number + size_increment;
|
115
|
+
for (i=num_objects; i < capacity_obj_offsets; i++) obj_offsets[i] = 0;
|
116
|
+
}
|
117
|
+
obj_offsets[obj_number] = offset;
|
118
|
+
if (obj_number >= num_objects) num_objects = obj_number + 1;
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
static void
|
123
|
+
Write_XObjects(int *ierr)
|
124
|
+
{
|
125
|
+
XObject_Info *xo;
|
126
|
+
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
127
|
+
Record_Object_Offset(xo->obj_num);
|
128
|
+
fprintf(OF, "%i 0 obj << /Type /XObject ", xo->obj_num);
|
129
|
+
switch (xo->xobj_subtype) {
|
130
|
+
case JPG_SUBTYPE:
|
131
|
+
Write_JPG((JPG_Info *)xo, ierr);
|
132
|
+
break;
|
133
|
+
case SAMPLED_SUBTYPE:
|
134
|
+
Write_Sampled((Sampled_Info *)xo, ierr);
|
135
|
+
break;
|
136
|
+
default:
|
137
|
+
RAISE_ERROR_i("Invalid XObject subtype (%i)", xo->xobj_subtype, ierr);
|
138
|
+
}
|
139
|
+
if (*ierr != 0) return;
|
140
|
+
fprintf(OF, ">> endobj\n");
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
#define INFO_OBJ 1
|
146
|
+
#define PAGES_OBJ 2
|
147
|
+
#define STREAM_OBJ 3
|
148
|
+
#define PAGE_OBJ 4
|
149
|
+
#define CATALOG_OBJ 5
|
150
|
+
#define FIRST_OTHER_OBJ 6
|
151
|
+
|
152
|
+
|
153
|
+
static void
|
154
|
+
Free_Records(int *ierr)
|
155
|
+
{
|
156
|
+
Free_Stroke_Opacities();
|
157
|
+
Free_Fill_Opacities();
|
158
|
+
Free_XObjects(ierr);
|
159
|
+
Free_Shadings();
|
160
|
+
Free_Functions();
|
161
|
+
}
|
162
|
+
|
163
|
+
|
164
|
+
static void
|
165
|
+
Get_pdf_name(char *ofile, char *filename, int maxlen)
|
166
|
+
{
|
167
|
+
char *dot;
|
168
|
+
strncpy(ofile, filename, maxlen);
|
169
|
+
dot = strrchr(ofile, '.');
|
170
|
+
if (dot != NULL) dot[0] = '\0';
|
171
|
+
strcat(ofile, "_figure.pdf");
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
void
|
176
|
+
Open_pdf(OBJ_PTR fmkr, FM *p, char *filename, bool quiet_mode, int *ierr)
|
177
|
+
{
|
178
|
+
int i;
|
179
|
+
if (writing_file) {
|
180
|
+
RAISE_ERROR("Sorry: cannot start a new output file until finish "
|
181
|
+
"current one.", ierr);
|
182
|
+
return;
|
183
|
+
}
|
184
|
+
Clear_Fonts_In_Use_Flags();
|
185
|
+
Free_Records(ierr);
|
186
|
+
if (*ierr != 0) return;
|
187
|
+
next_available_object_number = FIRST_OTHER_OBJ;
|
188
|
+
next_available_font_number = num_predefined_fonts + 1;
|
189
|
+
next_available_gs_number = 1;
|
190
|
+
next_available_xo_number = 1;
|
191
|
+
next_available_shade_number = 1;
|
192
|
+
writing_file = true;
|
193
|
+
time_t now = time(NULL);
|
194
|
+
char ofile[300], timestring[100];
|
195
|
+
Get_pdf_name(ofile, filename, 300);
|
196
|
+
if ((OF = fopen(ofile, "w")) == NULL) {
|
197
|
+
RAISE_ERROR_s("Sorry: can't open %s.\n", filename, ierr);
|
198
|
+
return;
|
199
|
+
}
|
200
|
+
if ((TF = tmpfile()) == NULL) {
|
201
|
+
RAISE_ERROR_s("Sorry: can't create temp file for writing PDF file %s.\n",
|
202
|
+
filename, ierr);
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
/* open PDF file and write header */
|
206
|
+
fprintf(OF, "%%PDF-1.4\n");
|
207
|
+
strcpy(timestring, ctime(&now));
|
208
|
+
i = strlen(timestring);
|
209
|
+
if (i > 0) timestring[i-1] = '\0';
|
210
|
+
Record_Object_Offset(INFO_OBJ);
|
211
|
+
fprintf(OF,
|
212
|
+
"%i 0 obj <<\n/Creator (Tioga)\n/CreationDate (%s)\n>>\nendobj\n",
|
213
|
+
INFO_OBJ, timestring);
|
214
|
+
Record_Object_Offset(PAGES_OBJ);
|
215
|
+
fprintf(OF,
|
216
|
+
"%i 0 obj <<\n/Type /Pages\n/Kids [%i 0 R]\n/Count 1\n>> endobj\n",
|
217
|
+
PAGES_OBJ, PAGE_OBJ);
|
218
|
+
Record_Object_Offset(STREAM_OBJ);
|
219
|
+
if (FLATE_ENCODE)
|
220
|
+
fprintf(OF, "%i 0 obj <<\t/Filter /FlateDecode /Length ", STREAM_OBJ);
|
221
|
+
else
|
222
|
+
fprintf(OF, "%i 0 obj <<\t/Length ", STREAM_OBJ);
|
223
|
+
length_offset = ftell(OF);
|
224
|
+
fprintf(OF, " \n>>\nstream\n");
|
225
|
+
stream_start = ftell(OF);
|
226
|
+
fprintf(TF, "%.2f 0 0 %.2f %.2f %.2f cm\n", 1.0/ENLARGE, 1.0/ENLARGE,
|
227
|
+
Get_pdf_xoffset(), Get_pdf_yoffset());
|
228
|
+
/* set stroke and fill colors to black */
|
229
|
+
have_current_point = constructing_path = false;
|
230
|
+
c_line_width_set(fmkr, p, p->line_width, ierr);
|
231
|
+
c_line_cap_set(fmkr, p, p->line_cap, ierr);
|
232
|
+
c_line_join_set(fmkr, p, p->line_join, ierr);
|
233
|
+
c_miter_limit_set(fmkr, p, p->miter_limit, ierr);
|
234
|
+
c_line_type_set(fmkr, p, Get_line_type(fmkr, ierr), ierr);
|
235
|
+
c_stroke_color_set_RGB(fmkr, p, p->stroke_color_R, p->stroke_color_G,
|
236
|
+
p->stroke_color_B, ierr);
|
237
|
+
c_fill_color_set_RGB(fmkr, p, p->fill_color_R, p->fill_color_G,
|
238
|
+
p->fill_color_B, ierr);
|
239
|
+
// initialize clip region
|
240
|
+
bbox_llx = bbox_lly = 1e5;
|
241
|
+
bbox_urx = bbox_ury = -1e5;
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
void
|
246
|
+
Start_Axis_Standard_State(OBJ_PTR fmkr, FM *p, double r, double g, double b,
|
247
|
+
double line_width, int *ierr)
|
248
|
+
{
|
249
|
+
fprintf(TF, "q 2 J [] 0 d\n");
|
250
|
+
c_line_width_set(fmkr, p, line_width, ierr);
|
251
|
+
c_stroke_color_set_RGB(fmkr, p, r, g, b, ierr);
|
252
|
+
/* 2 J sets the line cap style to square cap */
|
253
|
+
/* set stroke and fill colors to black. set line type to solid */
|
254
|
+
}
|
255
|
+
|
256
|
+
|
257
|
+
void
|
258
|
+
End_Axis_Standard_State(void)
|
259
|
+
{
|
260
|
+
Write_grestore();
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
void
|
265
|
+
Write_gsave(void)
|
266
|
+
{
|
267
|
+
fprintf(TF, "q\n");
|
268
|
+
}
|
269
|
+
|
270
|
+
|
271
|
+
void
|
272
|
+
Write_grestore(void)
|
273
|
+
{
|
274
|
+
fprintf(TF, "Q\n");
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
void
|
279
|
+
c_pdf_gsave(OBJ_PTR fmkr, FM *p, int *ierr)
|
280
|
+
{
|
281
|
+
Write_gsave();
|
282
|
+
}
|
283
|
+
|
284
|
+
|
285
|
+
void
|
286
|
+
c_pdf_grestore(OBJ_PTR fmkr, FM *p, int *ierr)
|
287
|
+
{
|
288
|
+
Write_grestore();
|
289
|
+
}
|
290
|
+
|
291
|
+
|
292
|
+
static void
|
293
|
+
Print_Xref(long int offset)
|
294
|
+
{
|
295
|
+
char line[80];
|
296
|
+
int i, len;
|
297
|
+
snprintf(line,sizeof(line), "%li", offset);
|
298
|
+
len = strlen(line);
|
299
|
+
for (i=0; i < 10-len; i++) fputc('0', OF);
|
300
|
+
fprintf(OF, "%s 00000 n \n", line);
|
301
|
+
}
|
302
|
+
|
303
|
+
|
304
|
+
static void
|
305
|
+
Write_Stream(int *ierr)
|
306
|
+
{
|
307
|
+
long int len = ftell(TF);
|
308
|
+
unsigned long int new_len = (len * 11) / 10 + 100;
|
309
|
+
unsigned char *buffer, *dest_buffer;
|
310
|
+
rewind(TF);
|
311
|
+
buffer = ALLOC_N_unsigned_char(len+1);
|
312
|
+
dest_buffer = ALLOC_N_unsigned_char(new_len+1);
|
313
|
+
fread(buffer, 1, len, TF);
|
314
|
+
fclose(TF);
|
315
|
+
if (FLATE_ENCODE) {
|
316
|
+
if (do_flate_compress(dest_buffer, &new_len, buffer, len) != FLATE_OK) {
|
317
|
+
free(buffer); free(dest_buffer);
|
318
|
+
RAISE_ERROR("Error compressing PDF stream data", ierr);
|
319
|
+
return;
|
320
|
+
}
|
321
|
+
fwrite(dest_buffer, 1, new_len, OF);
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
fwrite(buffer, 1, len, OF);
|
325
|
+
}
|
326
|
+
free(buffer);
|
327
|
+
free(dest_buffer);
|
328
|
+
}
|
329
|
+
|
330
|
+
|
331
|
+
void
|
332
|
+
Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
333
|
+
{
|
334
|
+
int i;
|
335
|
+
double llx, lly, urx, ury, xoff, yoff;
|
336
|
+
if (!writing_file) {
|
337
|
+
RAISE_ERROR("Sorry: cannot End_Output if not writing file.", ierr);
|
338
|
+
return;
|
339
|
+
}
|
340
|
+
writing_file = false;
|
341
|
+
if (constructing_path) {
|
342
|
+
RAISE_ERROR("Sorry: must finish with current path before ending file",
|
343
|
+
ierr);
|
344
|
+
return;
|
345
|
+
}
|
346
|
+
Write_Stream(ierr);
|
347
|
+
if (*ierr != 0) return;
|
348
|
+
stream_end = ftell(OF);
|
349
|
+
fprintf(OF, "endstream\nendobj\n");
|
350
|
+
Record_Object_Offset(PAGE_OBJ);
|
351
|
+
fprintf(OF, "%i 0 obj <<\n/Type /Page\n/Parent %i 0 R\n/MediaBox [ ",
|
352
|
+
PAGE_OBJ, PAGES_OBJ);
|
353
|
+
if (bbox_llx < p->page_left) bbox_llx = p->page_left;
|
354
|
+
if (bbox_lly < p->page_bottom) bbox_lly = p->page_bottom;
|
355
|
+
if (bbox_urx > p->page_left + p->page_width)
|
356
|
+
bbox_urx = p->page_left + p->page_width;
|
357
|
+
if (bbox_ury > p->page_bottom + p->page_height)
|
358
|
+
bbox_ury = p->page_bottom + p->page_height;
|
359
|
+
//#define MARGIN 3
|
360
|
+
#define MARGIN 0
|
361
|
+
xoff = Get_pdf_xoffset();
|
362
|
+
yoff = Get_pdf_yoffset();
|
363
|
+
llx = bbox_llx / ENLARGE + xoff - MARGIN; // convert back to points
|
364
|
+
lly = bbox_lly / ENLARGE + yoff - MARGIN;
|
365
|
+
urx = bbox_urx / ENLARGE + xoff + MARGIN;
|
366
|
+
ury = bbox_ury / ENLARGE + yoff + MARGIN;
|
367
|
+
if (urx < llx || ury < lly) {
|
368
|
+
RAISE_ERROR("Sorry: Empty plot!", ierr);
|
369
|
+
return;
|
370
|
+
}
|
371
|
+
fprintf(OF, "%d %d %d %d", ROUND(llx), ROUND(lly), ROUND(urx), ROUND(ury));
|
372
|
+
fprintf(OF, " ]\n/Contents %i 0 R\n/Resources << "
|
373
|
+
"/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n", STREAM_OBJ);
|
374
|
+
if (Used_Any_Fonts()) {
|
375
|
+
Font_Dictionary *f;
|
376
|
+
fprintf(OF, " /Font <<\n ");
|
377
|
+
for (f = font_dictionaries; f != NULL; f = f->next) {
|
378
|
+
if (!f->in_use) continue;
|
379
|
+
fprintf(OF, " /F%i %i 0 R\n", f->font_num, f->obj_num);
|
380
|
+
}
|
381
|
+
fprintf(OF, " >>\n"); // end of /Font
|
382
|
+
}
|
383
|
+
if (fill_opacities != NULL || stroke_opacities != NULL) {
|
384
|
+
// ExtGstate objects go here
|
385
|
+
Fill_Opacity_State *pf;
|
386
|
+
Stroke_Opacity_State *ps;
|
387
|
+
fprintf(OF, " /ExtGState <<\n");
|
388
|
+
for (ps = stroke_opacities; ps != NULL; ps = ps->next) {
|
389
|
+
fprintf(OF, " /GS%i %i 0 R\n", ps->gs_num, ps->obj_num);
|
390
|
+
}
|
391
|
+
for (pf = fill_opacities; pf != NULL; pf = pf->next) {
|
392
|
+
fprintf(OF, " /GS%i %i 0 R\n", pf->gs_num, pf->obj_num);
|
393
|
+
}
|
394
|
+
fprintf(OF, " >>\n"); // end of /ExtGState
|
395
|
+
}
|
396
|
+
if (xobj_list != NULL) {
|
397
|
+
// Xobjects go here
|
398
|
+
XObject_Info *xo;
|
399
|
+
fprintf(OF, " /XObject <<\n");
|
400
|
+
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
401
|
+
fprintf(OF, " /XObj%i %i 0 R\n", xo->xo_num, xo->obj_num);
|
402
|
+
}
|
403
|
+
fprintf(OF, " >>\n"); // end of /XObject
|
404
|
+
}
|
405
|
+
if (shades_list != NULL) {
|
406
|
+
// Shadings go here
|
407
|
+
Shading_Info *so;
|
408
|
+
fprintf(OF, " /Shading <<\n");
|
409
|
+
for (so = shades_list; so != NULL; so = so->next) {
|
410
|
+
fprintf(OF, " /Shade%i %i 0 R\n", so->shade_num, so->obj_num);
|
411
|
+
}
|
412
|
+
fprintf(OF, " >>\n"); // end of /Shading
|
413
|
+
}
|
414
|
+
fprintf(OF, " >>\n"); // end of /Resources
|
415
|
+
fprintf(OF, ">> endobj\n");
|
416
|
+
Record_Object_Offset(CATALOG_OBJ);
|
417
|
+
fprintf(OF, "%i 0 obj <<\n/Type /Catalog\n/Pages %i 0 R\n>> endobj\n",
|
418
|
+
CATALOG_OBJ, PAGES_OBJ);
|
419
|
+
Write_Font_Dictionaries();
|
420
|
+
Write_Font_Descriptors();
|
421
|
+
Write_Font_Widths();
|
422
|
+
Write_Stroke_Opacity_Objects();
|
423
|
+
Write_Fill_Opacity_Objects();
|
424
|
+
Write_XObjects(ierr);
|
425
|
+
if (*ierr != 0) return;
|
426
|
+
Write_Functions(ierr);
|
427
|
+
if (*ierr != 0) return;
|
428
|
+
Write_Shadings();
|
429
|
+
xref_offset = ftell(OF);
|
430
|
+
fprintf(OF, "xref\n0 %li\n0000000000 65535 f \n", num_objects);
|
431
|
+
for (i = 1; i < num_objects; i++)
|
432
|
+
Print_Xref(obj_offsets[i]); // NB: DONT USE OBJECT 0
|
433
|
+
fprintf(OF, "trailer\n<<\n/Size %li\n/Root %i 0 R\n/Info %i 0 "
|
434
|
+
"R\n>>\nstartxref\n%li\n%%%%EOF\n",
|
435
|
+
num_objects, CATALOG_OBJ, INFO_OBJ, xref_offset);
|
436
|
+
fseek(OF, length_offset, SEEK_SET);
|
437
|
+
fprintf(OF, "%li", stream_end - stream_start);
|
438
|
+
fclose(OF);
|
439
|
+
Free_Records(ierr);
|
440
|
+
}
|
441
|
+
|
442
|
+
|
443
|
+
void
|
444
|
+
Rename_pdf(char *oldname, char *newname)
|
445
|
+
{
|
446
|
+
char old_ofile[300], new_ofile[300];
|
447
|
+
Get_pdf_name(old_ofile, oldname, 300);
|
448
|
+
Get_pdf_name(new_ofile, newname, 300);
|
449
|
+
rename(old_ofile, new_ofile); // from stdio.h
|
450
|
+
}
|
451
|
+
|
@@ -0,0 +1,539 @@
|
|
1
|
+
/* pdfimage.c */
|
2
|
+
/*
|
3
|
+
Copyright (C) 2005 Bill Paxton
|
4
|
+
|
5
|
+
This file is part of Tioga.
|
6
|
+
|
7
|
+
Tioga is free software; you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU General Library Public License as published
|
9
|
+
by the Free Software Foundation; either version 2 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
Tioga is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Library General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Library General Public License
|
18
|
+
along with Tioga; if not, write to the Free Software
|
19
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include "figures.h"
|
23
|
+
#include "pdfs.h"
|
24
|
+
|
25
|
+
/* Images
|
26
|
+
|
27
|
+
invoke image by "/Image_name Do" in the content stream
|
28
|
+
|
29
|
+
the resources dictionary must have image object names in XObject dictionary
|
30
|
+
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
31
|
+
/XObject <<
|
32
|
+
/Image_name 30 0 R
|
33
|
+
...
|
34
|
+
>>
|
35
|
+
|
36
|
+
30 0 obj <<
|
37
|
+
/Type /XObject
|
38
|
+
/Subtype /Image
|
39
|
+
/Width <integer> number of columns. required for all.
|
40
|
+
/Height <integer> number of rows. required for all.
|
41
|
+
/Length <integer> number of bytes in image data stream. required for all.
|
42
|
+
/Interpolate <boolean> optional for all.
|
43
|
+
/SMask <stream> optional for all.
|
44
|
+
...
|
45
|
+
>>
|
46
|
+
stream
|
47
|
+
...image data...
|
48
|
+
endstream
|
49
|
+
endobj
|
50
|
+
|
51
|
+
For JPEG2000 images:
|
52
|
+
/Filter /JPXDecode
|
53
|
+
/Mask <image_mask_name> for explicit masking. optional.
|
54
|
+
|
55
|
+
For JPEG images:
|
56
|
+
/Filter /DCTDecode
|
57
|
+
/ColorSpace <name or array>. required. /DeviceRGB ?
|
58
|
+
/BitsPerComponent 8
|
59
|
+
/Mask <image_mask_name> for explicit masking. optional.
|
60
|
+
|
61
|
+
For sampled images:
|
62
|
+
/Filter <name> whatever filter being used for the image data. optional.
|
63
|
+
/ColorSpace <name or array>. required.
|
64
|
+
/BitsPerComponent 8
|
65
|
+
/Mask <image_mask_name> for explicit masking. optional.
|
66
|
+
/Mask [min, max] for masking out specified sample values.
|
67
|
+
for example, you can use 0 to stand for "undefined", then setting /Mask [0 0] will cause all
|
68
|
+
0 valued samples to be masked out of the image.
|
69
|
+
|
70
|
+
For image masks:
|
71
|
+
/ImageMask true
|
72
|
+
/BitsPerComponent 1
|
73
|
+
/Decode [0 1] means sample values of 0 are included in the output, values of 1 are excluded
|
74
|
+
/Decode [1 0] means sample values of 1 are included in the output, values of 0 are excluded
|
75
|
+
|
76
|
+
*/
|
77
|
+
|
78
|
+
|
79
|
+
void
|
80
|
+
Free_JPG(JPG_Info *xo)
|
81
|
+
{
|
82
|
+
if (xo->filename != NULL) free(xo->filename);
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
void
|
87
|
+
Free_Sampled(Sampled_Info *xo)
|
88
|
+
{
|
89
|
+
if (xo->image_data != NULL) free(xo->image_data);
|
90
|
+
if (xo->lookup != NULL) free(xo->lookup);
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
static bool
|
95
|
+
Is_monochrome(int obj_num)
|
96
|
+
{
|
97
|
+
XObject_Info *xo;
|
98
|
+
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
99
|
+
if (xo->xobj_subtype == SAMPLED_SUBTYPE && xo->obj_num == obj_num) {
|
100
|
+
Sampled_Info *p = (Sampled_Info *)xo;
|
101
|
+
return (p->image_type == MONO_IMAGE);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return false;
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
static void
|
109
|
+
Write_Image_From_File(char *filename, int width, int height, char *out_info,
|
110
|
+
int mask_obj_num, int *ierr)
|
111
|
+
{
|
112
|
+
FILE *jpg = fopen(filename, "r");
|
113
|
+
if (jpg == NULL) {
|
114
|
+
RAISE_ERROR_s("Sorry: cannot open file for showing image (%s)\n",
|
115
|
+
filename, ierr);
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
unsigned char *buff;
|
119
|
+
int len, rd_len;
|
120
|
+
int buff_len = 256000;
|
121
|
+
buff = ALLOC_N_unsigned_char(buff_len);
|
122
|
+
len = 0;
|
123
|
+
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) {
|
124
|
+
len += buff_len;
|
125
|
+
}
|
126
|
+
len += rd_len;
|
127
|
+
fprintf(OF, "\t/Subtype /Image\n");
|
128
|
+
if (mask_obj_num > 0) {
|
129
|
+
if (!Is_monochrome(mask_obj_num))
|
130
|
+
fprintf(OF, "\t/SMask %i 0 R\n", mask_obj_num);
|
131
|
+
else
|
132
|
+
fprintf(OF, "\t/Mask %i 0 R\n", mask_obj_num);
|
133
|
+
}
|
134
|
+
fprintf(OF, "\t/Width %i\n", width);
|
135
|
+
fprintf(OF, "\t/Height %i\n", height);
|
136
|
+
fprintf(OF, "%s", out_info);
|
137
|
+
fprintf(OF, "\t/Length %i\n\t>>\nstream\n", len);
|
138
|
+
if (len < buff_len) fwrite(buff, 1, len, OF);
|
139
|
+
else {
|
140
|
+
rewind(jpg);
|
141
|
+
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) {
|
142
|
+
fwrite(buff, 1, buff_len, OF);
|
143
|
+
}
|
144
|
+
fwrite(buff, 1, rd_len, OF);
|
145
|
+
}
|
146
|
+
fprintf(OF, "\nendstream\n");
|
147
|
+
fclose(jpg);
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
void
|
152
|
+
Write_JPG(JPG_Info *xo, int *ierr)
|
153
|
+
{
|
154
|
+
Write_Image_From_File(xo->filename, xo->width, xo->height,
|
155
|
+
"\t/Filter /DCTDecode\n\t/ColorSpace "
|
156
|
+
"/DeviceRGB\n\t/BitsPerComponent 8\n",
|
157
|
+
xo->mask_obj_num, ierr);
|
158
|
+
}
|
159
|
+
|
160
|
+
extern void
|
161
|
+
str_hls_to_rgb_bang(unsigned char* str, long len);
|
162
|
+
|
163
|
+
void
|
164
|
+
Write_Sampled(Sampled_Info *xo, int *ierr)
|
165
|
+
{
|
166
|
+
fprintf(OF, "\n\t/Subtype /Image\n");
|
167
|
+
fprintf(OF, "\t/Filter /FlateDecode\n\t/Interpolate %s\n",
|
168
|
+
(xo->interpolate)? "true":"false");
|
169
|
+
fprintf(OF, "\t/Height %i\n", xo->height);
|
170
|
+
fprintf(OF, "\t/Width %i\n", xo->width);
|
171
|
+
int i, len;
|
172
|
+
unsigned long new_len;
|
173
|
+
unsigned char *image_data;
|
174
|
+
unsigned char *buffer;
|
175
|
+
switch (xo->image_type) {
|
176
|
+
case RGB_IMAGE:
|
177
|
+
case HLS_IMAGE:
|
178
|
+
fprintf(OF, "\t/ColorSpace /DeviceRGB\n");
|
179
|
+
fprintf(OF, "\t/BitsPerComponent 8\n");
|
180
|
+
break;
|
181
|
+
case CMYK_IMAGE:
|
182
|
+
fprintf(OF, "\t/ColorSpace /DeviceCMYK\n");
|
183
|
+
fprintf(OF, "\t/BitsPerComponent 8\n");
|
184
|
+
break;
|
185
|
+
case GRAY_IMAGE:
|
186
|
+
fprintf(OF, "\t/ColorSpace /DeviceGray\n");
|
187
|
+
fprintf(OF, "\t/BitsPerComponent 8\n");
|
188
|
+
break;
|
189
|
+
case MONO_IMAGE:
|
190
|
+
fprintf(OF, "\t/ImageMask true\n");
|
191
|
+
fprintf(OF, "\t/BitsPerComponent 1\n");
|
192
|
+
if (!xo->reversed) fprintf(OF, "\t/Decode [0 1]\n");
|
193
|
+
else fprintf(OF, "\t/Decode [1 0]\n");
|
194
|
+
break;
|
195
|
+
default:
|
196
|
+
len = xo->lookup_len;
|
197
|
+
fprintf(OF, "\t/ColorSpace [ /Indexed /DeviceRGB %i <", xo->hival);
|
198
|
+
for (i = 0; i < len; i++) {
|
199
|
+
unsigned char c = xo->lookup[i];
|
200
|
+
if (c == 0) fprintf(OF, "00");
|
201
|
+
else if (c < 16) fprintf(OF, "0%x", c);
|
202
|
+
else fprintf(OF, "%x", c);
|
203
|
+
}
|
204
|
+
fprintf(OF, "> ]\n");
|
205
|
+
fprintf(OF, "\t/BitsPerComponent 8\n");
|
206
|
+
}
|
207
|
+
if (xo->mask_obj_num > 0) {
|
208
|
+
if (xo->image_type == MONO_IMAGE) {
|
209
|
+
RAISE_ERROR("Sorry: monochrome images must not have masks", ierr);
|
210
|
+
return;
|
211
|
+
}
|
212
|
+
if (!Is_monochrome(xo->mask_obj_num))
|
213
|
+
fprintf(OF, "\t/SMask %i 0 R\n", xo->mask_obj_num);
|
214
|
+
else
|
215
|
+
fprintf(OF, "\t/Mask %i 0 R\n", xo->mask_obj_num);
|
216
|
+
}
|
217
|
+
if (xo->value_mask_min >= 0 && xo->value_mask_max >= 0
|
218
|
+
&& xo->value_mask_min <= 255 && xo->value_mask_max <= 255
|
219
|
+
&& xo->value_mask_min <= xo->value_mask_max)
|
220
|
+
fprintf(OF, "\t/Mask [%i %i]\n", xo->value_mask_min, xo->value_mask_max);
|
221
|
+
|
222
|
+
if (xo->image_type == HLS_IMAGE) {
|
223
|
+
image_data = ALLOC_N_unsigned_char(xo->length);
|
224
|
+
memcpy(image_data, xo->image_data, xo->length);
|
225
|
+
str_hls_to_rgb_bang(image_data, xo->length);
|
226
|
+
} else {
|
227
|
+
image_data = xo->image_data;
|
228
|
+
}
|
229
|
+
|
230
|
+
new_len = (xo->length * 11)/10 + 100;
|
231
|
+
buffer = ALLOC_N_unsigned_char(new_len);
|
232
|
+
if (do_flate_compress(buffer, &new_len, image_data, xo->length)
|
233
|
+
!= FLATE_OK) {
|
234
|
+
free(buffer);
|
235
|
+
RAISE_ERROR("Error compressing image data", ierr);
|
236
|
+
return;
|
237
|
+
}
|
238
|
+
fprintf(OF, "\t/Length %li\n", new_len);
|
239
|
+
fprintf(OF, "\t>>\nstream\n");
|
240
|
+
if (fwrite(buffer, 1, new_len, OF) < new_len) {
|
241
|
+
RAISE_ERROR("Error writing image data", ierr);
|
242
|
+
return;
|
243
|
+
}
|
244
|
+
free(buffer);
|
245
|
+
if (xo->image_type == HLS_IMAGE) free(image_data);
|
246
|
+
fprintf(OF, "\nendstream\nendobj\n");
|
247
|
+
}
|
248
|
+
|
249
|
+
|
250
|
+
// transform maps (0,0), (1,0), and (0,1) to the given points
|
251
|
+
static void
|
252
|
+
Create_Transform_from_Points(double llx, double lly, double lrx, double lry,
|
253
|
+
double ulx, double uly, double *a, double *b,
|
254
|
+
double *c, double *d, double *e, double *f)
|
255
|
+
{
|
256
|
+
*e = llx; *f = lly; lrx -= llx; ulx -= llx; lry -= lly; uly -= lly;
|
257
|
+
*a = lrx; *b = lry; *c = ulx; *d = uly;
|
258
|
+
}
|
259
|
+
|
260
|
+
|
261
|
+
static void
|
262
|
+
Get_Image_Dest(FM *p, OBJ_PTR image_destination, double *dest, int *ierr)
|
263
|
+
{
|
264
|
+
int len = Array_Len(image_destination,ierr);
|
265
|
+
if (*ierr != 0) return;
|
266
|
+
if (len != 6) {
|
267
|
+
RAISE_ERROR("Sorry: invalid image destination array: "
|
268
|
+
"must have 6 entries", ierr);
|
269
|
+
return;
|
270
|
+
}
|
271
|
+
int i;
|
272
|
+
for (i = 0; i < 6; i++) {
|
273
|
+
OBJ_PTR entry = Array_Entry(image_destination, i, ierr);
|
274
|
+
if (*ierr != 0) return;
|
275
|
+
if (i % 2 == 0)
|
276
|
+
dest[i] = convert_figure_to_output_x(p,Number_to_double(entry, ierr));
|
277
|
+
else
|
278
|
+
dest[i] = convert_figure_to_output_y(p,Number_to_double(entry, ierr));
|
279
|
+
if (*ierr != 0) return;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
|
284
|
+
static void
|
285
|
+
Show_JPEG(FM *p, char *filename, int width, int height, double *dest,
|
286
|
+
int subtype, int mask_obj_num)
|
287
|
+
{
|
288
|
+
JPG_Info *xo = (JPG_Info *)calloc(1,sizeof(JPG_Info));
|
289
|
+
xo->xobj_subtype = subtype;
|
290
|
+
double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3],
|
291
|
+
ulx = dest[4], uly = dest[5];
|
292
|
+
double a, b, c, d, e, f; // the transform to position the image
|
293
|
+
xo->next = xobj_list;
|
294
|
+
xobj_list = (XObject_Info *)xo;
|
295
|
+
xo->xo_num = next_available_xo_number++;
|
296
|
+
xo->obj_num = next_available_object_number++;
|
297
|
+
xo->filename = ALLOC_N_char(strlen(filename)+1);
|
298
|
+
strcpy(xo->filename, filename);
|
299
|
+
xo->width = width;
|
300
|
+
xo->height = height;
|
301
|
+
xo->mask_obj_num = mask_obj_num;
|
302
|
+
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
303
|
+
&a, &b, &c, &d, &e, &f);
|
304
|
+
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
305
|
+
a, b, c, d, e, f, xo->xo_num);
|
306
|
+
update_bbox(p, llx, lly);
|
307
|
+
update_bbox(p, lrx, lry);
|
308
|
+
update_bbox(p, ulx, uly);
|
309
|
+
update_bbox(p, lrx+ulx-llx, lry+uly-lly);
|
310
|
+
}
|
311
|
+
|
312
|
+
|
313
|
+
void
|
314
|
+
c_private_show_jpg(OBJ_PTR fmkr, FM *p, char *filename,
|
315
|
+
int width, int height, OBJ_PTR image_destination,
|
316
|
+
int mask_obj_num, int *ierr)
|
317
|
+
{
|
318
|
+
double dest[6];
|
319
|
+
if (constructing_path) {
|
320
|
+
RAISE_ERROR("Sorry: must finish with current path before "
|
321
|
+
"calling show_jpg", ierr);
|
322
|
+
return;
|
323
|
+
}
|
324
|
+
Get_Image_Dest(p, image_destination, dest, ierr);
|
325
|
+
if (*ierr != 0) return;
|
326
|
+
Show_JPEG(p, filename, width, height, dest, JPG_SUBTYPE, mask_obj_num);
|
327
|
+
}
|
328
|
+
|
329
|
+
|
330
|
+
OBJ_PTR
|
331
|
+
c_private_create_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR table,
|
332
|
+
int first_row, int last_row, int first_column,
|
333
|
+
int last_column, double min_val, double max_val,
|
334
|
+
int max_code, int if_below_range,
|
335
|
+
int if_above_range, int *ierr)
|
336
|
+
{
|
337
|
+
long num_cols, num_rows;
|
338
|
+
double **data = Table_Data_for_Read(table, &num_cols, &num_rows, ierr);
|
339
|
+
if (*ierr != 0) RETURN_NIL;
|
340
|
+
if (first_column < 0) first_column += num_cols;
|
341
|
+
if (first_column < 0 || first_column >= num_cols)
|
342
|
+
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
343
|
+
first_column, ierr);
|
344
|
+
if (last_column < 0) last_column += num_cols;
|
345
|
+
if (last_column < 0 || last_column >= num_cols)
|
346
|
+
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
347
|
+
last_column, ierr);
|
348
|
+
if (first_row < 0) first_row += num_rows;
|
349
|
+
if (first_row < 0 || first_row >= num_rows)
|
350
|
+
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
351
|
+
first_row, ierr);
|
352
|
+
if (last_row < 0) last_row += num_rows;
|
353
|
+
if (last_row < 0 || last_row >= num_rows)
|
354
|
+
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
355
|
+
last_row, ierr);
|
356
|
+
if (min_val >= max_val)
|
357
|
+
RAISE_ERROR_gg("Sorry: invalid range specification: min %g max %g",
|
358
|
+
min_val, max_val, ierr);
|
359
|
+
if (max_code <= 0 || max_code > 255)
|
360
|
+
RAISE_ERROR_i("Sorry: invalid max_code specification (%i)",
|
361
|
+
max_code, ierr);
|
362
|
+
if (if_below_range < 0 || if_below_range > 255)
|
363
|
+
RAISE_ERROR_i("Sorry: invalid if_below_range specification (%i)",
|
364
|
+
if_below_range, ierr);
|
365
|
+
if (if_above_range < 0 || if_above_range > 255)
|
366
|
+
RAISE_ERROR_i("Sorry: invalid if_above_range specification (%i)",
|
367
|
+
if_above_range, ierr);
|
368
|
+
int i, j, k;
|
369
|
+
int width = last_column - first_column + 1;
|
370
|
+
int height = last_row - first_row + 1;
|
371
|
+
int sz = width * height;
|
372
|
+
if (sz <= 0)
|
373
|
+
RAISE_ERROR_ii("Sorry: invalid data specification: width (%i) "
|
374
|
+
"height (%i)", width, height, ierr);
|
375
|
+
if (*ierr != 0) RETURN_NIL;
|
376
|
+
char *buff = ALLOC_N_char(sz);
|
377
|
+
for (k = 0, i = first_row; i <= last_row; i++) {
|
378
|
+
double *row = data[i];
|
379
|
+
for (j = first_column; j <= last_column; j++) {
|
380
|
+
double val = row[j];
|
381
|
+
if (val < min_val) buff[k++] = if_below_range;
|
382
|
+
else if (val > max_val) buff[k++] = if_above_range;
|
383
|
+
else {
|
384
|
+
val = max_code * (val - min_val)/(max_val - min_val);
|
385
|
+
buff[k++] = ROUND(val);
|
386
|
+
}
|
387
|
+
}
|
388
|
+
}
|
389
|
+
OBJ_PTR result = String_New(buff, sz);
|
390
|
+
free(buff);
|
391
|
+
return result;
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
OBJ_PTR
|
396
|
+
c_private_create_monochrome_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR table,
|
397
|
+
int first_row, int last_row,
|
398
|
+
int first_column, int last_column,
|
399
|
+
double boundary, bool reversed,
|
400
|
+
int *ierr)
|
401
|
+
{
|
402
|
+
long num_cols, num_rows;
|
403
|
+
double **data = Table_Data_for_Read(table, &num_cols, &num_rows, ierr);
|
404
|
+
if (*ierr != 0) RETURN_NIL;
|
405
|
+
if (first_column < 0) first_column += num_cols;
|
406
|
+
if (first_column < 0 || first_column >= num_cols)
|
407
|
+
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
408
|
+
first_column, ierr);
|
409
|
+
if (last_column < 0) last_column += num_cols;
|
410
|
+
if (last_column < 0 || last_column >= num_cols)
|
411
|
+
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
412
|
+
last_column, ierr);
|
413
|
+
if (first_row < 0) first_row += num_rows;
|
414
|
+
if (first_row < 0 || first_row >= num_rows)
|
415
|
+
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
416
|
+
first_row, ierr);
|
417
|
+
if (last_row < 0) last_row += num_rows;
|
418
|
+
if (last_row < 0 || last_row >= num_rows)
|
419
|
+
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
420
|
+
last_row, ierr);
|
421
|
+
int i, j, k;
|
422
|
+
int width = last_column - first_column + 1;
|
423
|
+
int height = last_row - first_row + 1;
|
424
|
+
int bytes_per_row = (width+7)/8;
|
425
|
+
int sz = bytes_per_row * 8 * height;
|
426
|
+
if (sz <= 0)
|
427
|
+
RAISE_ERROR_ii("Sorry: invalid data specification: width (%i) "
|
428
|
+
"height (%i)", width, height, ierr);
|
429
|
+
if (*ierr != 0) RETURN_NIL;
|
430
|
+
// to simplify the process, do it in two stages: first get the
|
431
|
+
// values and then pack the bits
|
432
|
+
char *buff = ALLOC_N_char(sz);
|
433
|
+
for (k = 0, i = first_row; i <= last_row; i++) {
|
434
|
+
double *row = data[i];
|
435
|
+
for (j = first_column; j <= last_column; j++) {
|
436
|
+
double val = row[j];
|
437
|
+
buff[k++] = (reversed)? (val <= boundary) : (val > boundary);
|
438
|
+
}
|
439
|
+
for (j = last_column+1; j < bytes_per_row * 8; j++) {
|
440
|
+
buff[k++] = 0;
|
441
|
+
}
|
442
|
+
}
|
443
|
+
int num_bytes = (sz+7) >> 3;
|
444
|
+
char *bits = ALLOC_N_char(num_bytes), c = 0;
|
445
|
+
int num_bits = num_bytes << 3;
|
446
|
+
for (i = 0, k = -1; i < num_bits; i++) {
|
447
|
+
int bit = (i < sz)? buff[i] : 0;
|
448
|
+
int which_bit = i & 7;
|
449
|
+
if (which_bit != 0) c |= bit << (7-which_bit);
|
450
|
+
else {
|
451
|
+
if (k >= 0) bits[k] = c;
|
452
|
+
k++; c = bit << 7;
|
453
|
+
}
|
454
|
+
}
|
455
|
+
bits[k] = c;
|
456
|
+
OBJ_PTR result = String_New(bits, num_bytes);
|
457
|
+
free(bits); free(buff);
|
458
|
+
return result;
|
459
|
+
}
|
460
|
+
|
461
|
+
|
462
|
+
OBJ_PTR
|
463
|
+
c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
464
|
+
double lly, double lrx, double lry, double ulx,
|
465
|
+
double uly, bool interpolate, bool reversed,
|
466
|
+
int w, int h, unsigned char* data, long len,
|
467
|
+
OBJ_PTR mask_min, OBJ_PTR mask_max, OBJ_PTR hivalue,
|
468
|
+
OBJ_PTR lookup_data, int mask_obj_num, int *ierr)
|
469
|
+
{
|
470
|
+
unsigned char *lookup = NULL;
|
471
|
+
int value_mask_min = 256, value_mask_max = 256, lookup_len = 0, hival = 0;
|
472
|
+
if (constructing_path) {
|
473
|
+
RAISE_ERROR("Sorry: must finish with current path before calling "
|
474
|
+
"show_image", ierr);
|
475
|
+
RETURN_NIL;
|
476
|
+
}
|
477
|
+
if (image_type == COLORMAP_IMAGE) {
|
478
|
+
value_mask_min = Number_to_int(mask_min, ierr);
|
479
|
+
value_mask_max = Number_to_int(mask_max, ierr);
|
480
|
+
hival = Number_to_int(hivalue, ierr);
|
481
|
+
lookup = (unsigned char *)(String_Ptr(lookup_data, ierr));
|
482
|
+
lookup_len = String_Len(lookup_data, ierr);
|
483
|
+
if (*ierr != 0) RETURN_NIL;
|
484
|
+
}
|
485
|
+
|
486
|
+
llx = convert_figure_to_output_x(p, llx);
|
487
|
+
lly = convert_figure_to_output_y(p, lly);
|
488
|
+
lrx = convert_figure_to_output_x(p, lrx);
|
489
|
+
lry = convert_figure_to_output_y(p, lry);
|
490
|
+
ulx = convert_figure_to_output_x(p, ulx);
|
491
|
+
uly = convert_figure_to_output_y(p, uly);
|
492
|
+
|
493
|
+
Sampled_Info *xo = (Sampled_Info *)calloc(1, sizeof(Sampled_Info));
|
494
|
+
xo->xobj_subtype = SAMPLED_SUBTYPE;
|
495
|
+
double a, b, c, d, e, f; // the transform to position the image
|
496
|
+
//int ir, ic, id;
|
497
|
+
xo->next = xobj_list;
|
498
|
+
xobj_list = (XObject_Info *)xo;
|
499
|
+
xo->xo_num = next_available_xo_number++;
|
500
|
+
xo->obj_num = next_available_object_number++;
|
501
|
+
xo->image_data = ALLOC_N_unsigned_char(len);
|
502
|
+
xo->length = len;
|
503
|
+
xo->interpolate = interpolate;
|
504
|
+
xo->reversed = reversed;
|
505
|
+
memcpy(xo->image_data, data, len);
|
506
|
+
xo->image_type = image_type;
|
507
|
+
if (image_type != COLORMAP_IMAGE) xo->lookup = NULL;
|
508
|
+
else {
|
509
|
+
if ((hival+1)*3 > lookup_len) {
|
510
|
+
RAISE_ERROR_ii("Sorry: color space hival (%i) is too large for "
|
511
|
+
"length of lookup table (%i)", hival, lookup_len,
|
512
|
+
ierr);
|
513
|
+
RETURN_NIL;
|
514
|
+
}
|
515
|
+
xo->hival = hival;
|
516
|
+
lookup_len = (hival+1) * 3;
|
517
|
+
xo->lookup = ALLOC_N_unsigned_char(lookup_len);
|
518
|
+
xo->lookup_len = lookup_len;
|
519
|
+
memcpy(xo->lookup, lookup, lookup_len);
|
520
|
+
}
|
521
|
+
xo->width = w;
|
522
|
+
xo->height = h;
|
523
|
+
xo->value_mask_min = value_mask_min;
|
524
|
+
xo->value_mask_max = value_mask_max;
|
525
|
+
xo->mask_obj_num = mask_obj_num;
|
526
|
+
if (mask_obj_num == -1)
|
527
|
+
return Integer_New(xo->obj_num); // this image is being used as
|
528
|
+
// an opacity mask
|
529
|
+
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
530
|
+
&a, &b, &c, &d, &e, &f);
|
531
|
+
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
532
|
+
a, b, c, d, e, f, xo->xo_num);
|
533
|
+
update_bbox(p, llx, lly);
|
534
|
+
update_bbox(p, lrx, lry);
|
535
|
+
update_bbox(p, ulx, uly);
|
536
|
+
update_bbox(p, lrx+ulx-llx, lry+uly-lly);
|
537
|
+
return Integer_New(xo->obj_num);
|
538
|
+
}
|
539
|
+
|