tioga 1.7 → 1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Tioga_README +45 -29
- data/split/Dvector/dvector.c +1 -1
- data/split/Tioga/{shared/axes.c → axes.c} +360 -36
- data/split/Tioga/figures.c +2 -1
- data/split/Tioga/figures.h +6 -2
- data/split/Tioga/generic.h +0 -1
- data/split/Tioga/lib/FigMkr.rb +3 -1
- data/split/Tioga/lib/X_and_Y_Axes.rb +74 -4
- data/split/Tioga/makers.c +1303 -0
- data/split/Tioga/{shared/pdf_font_dicts.c → pdf_font_dicts.c} +0 -0
- data/split/Tioga/{shared/pdfcolor.c → pdfcolor.c} +304 -145
- data/split/Tioga/pdfcoords.c +534 -0
- data/split/Tioga/{shared/pdffile.c → pdffile.c} +161 -56
- data/split/Tioga/{shared/pdfimage.c → pdfimage.c} +171 -74
- data/split/Tioga/{shared/pdfpath.c → pdfpath.c} +0 -0
- data/split/Tioga/{shared/pdftext.c → pdftext.c} +245 -138
- data/split/Tioga/{shared/texout.c → texout.c} +18 -9
- data/split/Tioga/wrappers.c +23 -7
- data/split/Tioga/wrappers.h +5 -3
- data/split/extconf.rb +1 -1
- metadata +25 -25
- data/split/Tioga/shared/makers.c +0 -1220
- data/split/Tioga/shared/pdfcoords.c +0 -443
@@ -28,7 +28,9 @@
|
|
28
28
|
#define Get_pdf_xoffset() 5.0
|
29
29
|
#define Get_pdf_yoffset() 5.0
|
30
30
|
|
31
|
-
|
31
|
+
|
32
|
+
/* must match the font numbers in FigureConstants.rb */
|
33
|
+
char *predefined_Fonts[] = {
|
32
34
|
NULL,
|
33
35
|
"Times-Roman",
|
34
36
|
"Times-Italic", // 2
|
@@ -44,12 +46,14 @@ char *predefined_Fonts[] = { /* must match the font numbers in FigureConstants.r
|
|
44
46
|
"Courier-BoldOblique",
|
45
47
|
"Symbol",
|
46
48
|
"ZapfDingbats" // 14
|
47
|
-
|
49
|
+
};
|
48
50
|
int num_predefined_fonts = 14;
|
49
51
|
int num_pdf_standard_fonts = 14;
|
50
52
|
|
51
|
-
long *obj_offsets, capacity_obj_offsets, stream_start, stream_end
|
52
|
-
long
|
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;
|
53
57
|
long next_available_shade_number, next_available_font_number;
|
54
58
|
Stroke_Opacity_State *stroke_opacities = NULL;
|
55
59
|
Fill_Opacity_State *fill_opacities = NULL;
|
@@ -61,24 +65,35 @@ Old_Font_Dictionary *old_font_dictionaries = NULL;
|
|
61
65
|
FILE *OF = NULL; // for the PDF file
|
62
66
|
FILE *TF = NULL; // for the temp file
|
63
67
|
|
68
|
+
|
64
69
|
/* PDF File Management */
|
65
70
|
|
66
|
-
static void
|
71
|
+
static void
|
72
|
+
Free_XObjects(int *ierr)
|
67
73
|
{
|
68
74
|
XObject_Info *xo;
|
69
75
|
while (xobj_list != NULL) {
|
70
76
|
xo = xobj_list;
|
71
77
|
xobj_list = xo->next;
|
72
78
|
switch (xo->xobj_subtype) {
|
73
|
-
|
74
|
-
|
75
|
-
|
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;
|
76
89
|
}
|
77
90
|
free(xo);
|
78
91
|
}
|
79
92
|
}
|
80
93
|
|
81
|
-
|
94
|
+
|
95
|
+
void
|
96
|
+
Init_pdf(int *ierr)
|
82
97
|
{
|
83
98
|
int i;
|
84
99
|
writing_file = false;
|
@@ -88,7 +103,9 @@ void Init_pdf(int *ierr)
|
|
88
103
|
for (i=0; i < capacity_obj_offsets; i++) obj_offsets[i] = 0;
|
89
104
|
}
|
90
105
|
|
91
|
-
|
106
|
+
|
107
|
+
void
|
108
|
+
Record_Object_Offset(int obj_number)
|
92
109
|
{
|
93
110
|
long int offset = ftell(OF);
|
94
111
|
if (obj_number >= capacity_obj_offsets) {
|
@@ -101,22 +118,30 @@ void Record_Object_Offset(int obj_number)
|
|
101
118
|
if (obj_number >= num_objects) num_objects = obj_number + 1;
|
102
119
|
}
|
103
120
|
|
104
|
-
|
121
|
+
|
122
|
+
static void
|
123
|
+
Write_XObjects(int *ierr)
|
105
124
|
{
|
106
125
|
XObject_Info *xo;
|
107
126
|
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
108
127
|
Record_Object_Offset(xo->obj_num);
|
109
128
|
fprintf(OF, "%i 0 obj << /Type /XObject ", xo->obj_num);
|
110
129
|
switch (xo->xobj_subtype) {
|
111
|
-
|
112
|
-
|
113
|
-
|
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);
|
114
138
|
}
|
115
139
|
if (*ierr != 0) return;
|
116
140
|
fprintf(OF, ">> endobj\n");
|
117
141
|
}
|
118
142
|
}
|
119
143
|
|
144
|
+
|
120
145
|
#define INFO_OBJ 1
|
121
146
|
#define PAGES_OBJ 2
|
122
147
|
#define STREAM_OBJ 3
|
@@ -124,24 +149,38 @@ static void Write_XObjects(int *ierr)
|
|
124
149
|
#define CATALOG_OBJ 5
|
125
150
|
#define FIRST_OTHER_OBJ 6
|
126
151
|
|
127
|
-
|
152
|
+
|
153
|
+
static void
|
154
|
+
Free_Records(int *ierr)
|
128
155
|
{
|
129
|
-
Free_Stroke_Opacities();
|
156
|
+
Free_Stroke_Opacities();
|
157
|
+
Free_Fill_Opacities();
|
158
|
+
Free_XObjects(ierr);
|
159
|
+
Free_Shadings();
|
160
|
+
Free_Functions();
|
130
161
|
}
|
131
162
|
|
132
|
-
|
163
|
+
|
164
|
+
static void
|
165
|
+
Get_pdf_name(char *ofile, char *filename, int maxlen)
|
133
166
|
{
|
134
167
|
char *dot;
|
135
168
|
strncpy(ofile, filename, maxlen);
|
136
|
-
dot = strrchr(ofile,'.');
|
169
|
+
dot = strrchr(ofile, '.');
|
137
170
|
if (dot != NULL) dot[0] = '\0';
|
138
171
|
strcat(ofile, "_figure.pdf");
|
139
172
|
}
|
140
173
|
|
141
|
-
|
174
|
+
|
175
|
+
void
|
176
|
+
Open_pdf(OBJ_PTR fmkr, FM *p, char *filename, bool quiet_mode, int *ierr)
|
177
|
+
{
|
142
178
|
int i;
|
143
179
|
if (writing_file) {
|
144
|
-
RAISE_ERROR("Sorry: cannot start a new output file until finish
|
180
|
+
RAISE_ERROR("Sorry: cannot start a new output file until finish "
|
181
|
+
"current one.", ierr);
|
182
|
+
return;
|
183
|
+
}
|
145
184
|
Clear_Fonts_In_Use_Flags();
|
146
185
|
Free_Records(ierr);
|
147
186
|
if (*ierr != 0) return;
|
@@ -155,18 +194,27 @@ void Open_pdf(OBJ_PTR fmkr, FM *p, char *filename, bool quiet_mode, int *ierr) {
|
|
155
194
|
char ofile[300], timestring[100];
|
156
195
|
Get_pdf_name(ofile, filename, 300);
|
157
196
|
if ((OF = fopen(ofile, "w")) == NULL) {
|
158
|
-
|
197
|
+
RAISE_ERROR_s("Sorry: can't open %s.\n", filename, ierr);
|
198
|
+
return;
|
199
|
+
}
|
159
200
|
if ((TF = tmpfile()) == NULL) {
|
160
|
-
|
201
|
+
RAISE_ERROR_s("Sorry: can't create temp file for writing PDF file %s.\n",
|
202
|
+
filename, ierr);
|
203
|
+
return;
|
204
|
+
}
|
161
205
|
/* open PDF file and write header */
|
162
206
|
fprintf(OF, "%%PDF-1.4\n");
|
163
207
|
strcpy(timestring, ctime(&now));
|
164
208
|
i = strlen(timestring);
|
165
209
|
if (i > 0) timestring[i-1] = '\0';
|
166
210
|
Record_Object_Offset(INFO_OBJ);
|
167
|
-
fprintf(OF,
|
211
|
+
fprintf(OF,
|
212
|
+
"%i 0 obj <<\n/Creator (Tioga)\n/CreationDate (%s)\n>>\nendobj\n",
|
213
|
+
INFO_OBJ, timestring);
|
168
214
|
Record_Object_Offset(PAGES_OBJ);
|
169
|
-
fprintf(OF,
|
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);
|
170
218
|
Record_Object_Offset(STREAM_OBJ);
|
171
219
|
if (FLATE_ENCODE)
|
172
220
|
fprintf(OF, "%i 0 obj <<\t/Filter /FlateDecode /Length ", STREAM_OBJ);
|
@@ -176,7 +224,7 @@ void Open_pdf(OBJ_PTR fmkr, FM *p, char *filename, bool quiet_mode, int *ierr) {
|
|
176
224
|
fprintf(OF, " \n>>\nstream\n");
|
177
225
|
stream_start = ftell(OF);
|
178
226
|
fprintf(TF, "%.2f 0 0 %.2f %.2f %.2f cm\n", 1.0/ENLARGE, 1.0/ENLARGE,
|
179
|
-
|
227
|
+
Get_pdf_xoffset(), Get_pdf_yoffset());
|
180
228
|
/* set stroke and fill colors to black */
|
181
229
|
have_current_point = constructing_path = false;
|
182
230
|
c_line_width_set(fmkr, p, p->line_width, ierr);
|
@@ -184,14 +232,20 @@ void Open_pdf(OBJ_PTR fmkr, FM *p, char *filename, bool quiet_mode, int *ierr) {
|
|
184
232
|
c_line_join_set(fmkr, p, p->line_join, ierr);
|
185
233
|
c_miter_limit_set(fmkr, p, p->miter_limit, ierr);
|
186
234
|
c_line_type_set(fmkr, p, Get_line_type(fmkr, ierr), ierr);
|
187
|
-
c_stroke_color_set_RGB(fmkr, p, p->stroke_color_R, p->stroke_color_G,
|
188
|
-
|
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);
|
189
239
|
// initialize clip region
|
190
240
|
bbox_llx = bbox_lly = 1e5;
|
191
241
|
bbox_urx = bbox_ury = -1e5;
|
192
242
|
}
|
193
243
|
|
194
|
-
|
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
|
+
{
|
195
249
|
fprintf(TF, "q 2 J [] 0 d\n");
|
196
250
|
c_line_width_set(fmkr, p, line_width, ierr);
|
197
251
|
c_stroke_color_set_RGB(fmkr, p, r, g, b, ierr);
|
@@ -199,31 +253,56 @@ void Start_Axis_Standard_State(OBJ_PTR fmkr, FM *p, double r, double g, double b
|
|
199
253
|
/* set stroke and fill colors to black. set line type to solid */
|
200
254
|
}
|
201
255
|
|
202
|
-
void End_Axis_Standard_State(void) { Write_grestore(); }
|
203
256
|
|
204
|
-
void
|
257
|
+
void
|
258
|
+
End_Axis_Standard_State(void)
|
259
|
+
{
|
260
|
+
Write_grestore();
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
void
|
265
|
+
Write_gsave(void)
|
205
266
|
{
|
206
267
|
fprintf(TF, "q\n");
|
207
268
|
}
|
208
269
|
|
209
|
-
|
270
|
+
|
271
|
+
void
|
272
|
+
Write_grestore(void)
|
210
273
|
{
|
211
274
|
fprintf(TF, "Q\n");
|
212
275
|
}
|
213
276
|
|
214
|
-
void c_pdf_gsave(OBJ_PTR fmkr, FM *p, int *ierr) { Write_gsave(); }
|
215
|
-
void c_pdf_grestore(OBJ_PTR fmkr, FM *p, int *ierr) { Write_grestore(); }
|
216
277
|
|
217
|
-
|
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
|
+
{
|
218
295
|
char line[80];
|
219
296
|
int i, len;
|
220
297
|
snprintf(line,sizeof(line), "%li", offset);
|
221
298
|
len = strlen(line);
|
222
299
|
for (i=0; i < 10-len; i++) fputc('0', OF);
|
223
300
|
fprintf(OF, "%s 00000 n \n", line);
|
224
|
-
|
301
|
+
}
|
302
|
+
|
225
303
|
|
226
|
-
static void
|
304
|
+
static void
|
305
|
+
Write_Stream(int *ierr)
|
227
306
|
{
|
228
307
|
long int len = ftell(TF);
|
229
308
|
unsigned long int new_len = (len * 11) / 10 + 100;
|
@@ -240,29 +319,43 @@ static void Write_Stream(int *ierr)
|
|
240
319
|
return;
|
241
320
|
}
|
242
321
|
fwrite(dest_buffer, 1, new_len, OF);
|
243
|
-
}
|
322
|
+
}
|
323
|
+
else {
|
244
324
|
fwrite(buffer, 1, len, OF);
|
245
|
-
}
|
246
|
-
free(buffer);
|
325
|
+
}
|
326
|
+
free(buffer);
|
327
|
+
free(dest_buffer);
|
247
328
|
}
|
248
329
|
|
249
|
-
|
330
|
+
|
331
|
+
void
|
332
|
+
Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
250
333
|
{
|
251
334
|
int i;
|
252
335
|
double llx, lly, urx, ury, xoff, yoff;
|
253
|
-
if (!writing_file) {
|
336
|
+
if (!writing_file) {
|
337
|
+
RAISE_ERROR("Sorry: cannot End_Output if not writing file.", ierr);
|
338
|
+
return;
|
339
|
+
}
|
254
340
|
writing_file = false;
|
255
|
-
if (constructing_path) {
|
341
|
+
if (constructing_path) {
|
342
|
+
RAISE_ERROR("Sorry: must finish with current path before ending file",
|
343
|
+
ierr);
|
344
|
+
return;
|
345
|
+
}
|
256
346
|
Write_Stream(ierr);
|
257
347
|
if (*ierr != 0) return;
|
258
348
|
stream_end = ftell(OF);
|
259
349
|
fprintf(OF, "endstream\nendobj\n");
|
260
350
|
Record_Object_Offset(PAGE_OBJ);
|
261
|
-
fprintf(OF, "%i 0 obj <<\n/Type /Page\n/Parent %i 0 R\n/MediaBox [ ",
|
351
|
+
fprintf(OF, "%i 0 obj <<\n/Type /Page\n/Parent %i 0 R\n/MediaBox [ ",
|
352
|
+
PAGE_OBJ, PAGES_OBJ);
|
262
353
|
if (bbox_llx < p->page_left) bbox_llx = p->page_left;
|
263
354
|
if (bbox_lly < p->page_bottom) bbox_lly = p->page_bottom;
|
264
|
-
if (bbox_urx > p->page_left + p->page_width)
|
265
|
-
|
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;
|
266
359
|
//#define MARGIN 3
|
267
360
|
#define MARGIN 0
|
268
361
|
xoff = Get_pdf_xoffset();
|
@@ -271,9 +364,13 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
271
364
|
lly = bbox_lly / ENLARGE + yoff - MARGIN;
|
272
365
|
urx = bbox_urx / ENLARGE + xoff + MARGIN;
|
273
366
|
ury = bbox_ury / ENLARGE + yoff + MARGIN;
|
274
|
-
if (urx < llx || ury < lly) {
|
367
|
+
if (urx < llx || ury < lly) {
|
368
|
+
RAISE_ERROR("Sorry: Empty plot!", ierr);
|
369
|
+
return;
|
370
|
+
}
|
275
371
|
fprintf(OF, "%d %d %d %d", ROUND(llx), ROUND(lly), ROUND(urx), ROUND(ury));
|
276
|
-
fprintf(OF, " ]\n/Contents %i 0 R\n/Resources <<
|
372
|
+
fprintf(OF, " ]\n/Contents %i 0 R\n/Resources << "
|
373
|
+
"/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n", STREAM_OBJ);
|
277
374
|
if (Used_Any_Fonts()) {
|
278
375
|
Font_Dictionary *f;
|
279
376
|
fprintf(OF, " /Font <<\n ");
|
@@ -283,7 +380,8 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
283
380
|
}
|
284
381
|
fprintf(OF, " >>\n"); // end of /Font
|
285
382
|
}
|
286
|
-
if (fill_opacities != NULL || stroke_opacities != NULL) {
|
383
|
+
if (fill_opacities != NULL || stroke_opacities != NULL) {
|
384
|
+
// ExtGstate objects go here
|
287
385
|
Fill_Opacity_State *pf;
|
288
386
|
Stroke_Opacity_State *ps;
|
289
387
|
fprintf(OF, " /ExtGState <<\n");
|
@@ -295,7 +393,8 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
295
393
|
}
|
296
394
|
fprintf(OF, " >>\n"); // end of /ExtGState
|
297
395
|
}
|
298
|
-
if (xobj_list != NULL) {
|
396
|
+
if (xobj_list != NULL) {
|
397
|
+
// Xobjects go here
|
299
398
|
XObject_Info *xo;
|
300
399
|
fprintf(OF, " /XObject <<\n");
|
301
400
|
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
@@ -303,7 +402,8 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
303
402
|
}
|
304
403
|
fprintf(OF, " >>\n"); // end of /XObject
|
305
404
|
}
|
306
|
-
if (shades_list != NULL) {
|
405
|
+
if (shades_list != NULL) {
|
406
|
+
// Shadings go here
|
307
407
|
Shading_Info *so;
|
308
408
|
fprintf(OF, " /Shading <<\n");
|
309
409
|
for (so = shades_list; so != NULL; so = so->next) {
|
@@ -314,7 +414,8 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
314
414
|
fprintf(OF, " >>\n"); // end of /Resources
|
315
415
|
fprintf(OF, ">> endobj\n");
|
316
416
|
Record_Object_Offset(CATALOG_OBJ);
|
317
|
-
fprintf(OF, "%i 0 obj <<\n/Type /Catalog\n/Pages %i 0 R\n>> endobj\n",
|
417
|
+
fprintf(OF, "%i 0 obj <<\n/Type /Catalog\n/Pages %i 0 R\n>> endobj\n",
|
418
|
+
CATALOG_OBJ, PAGES_OBJ);
|
318
419
|
Write_Font_Dictionaries();
|
319
420
|
Write_Font_Descriptors();
|
320
421
|
Write_Font_Widths();
|
@@ -326,17 +427,21 @@ void Close_pdf(OBJ_PTR fmkr, FM *p, bool quiet_mode, int *ierr)
|
|
326
427
|
if (*ierr != 0) return;
|
327
428
|
Write_Shadings();
|
328
429
|
xref_offset = ftell(OF);
|
329
|
-
fprintf(OF, "xref\n0 %
|
330
|
-
for (i = 1; i < num_objects; i++)
|
331
|
-
|
332
|
-
|
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);
|
333
436
|
fseek(OF, length_offset, SEEK_SET);
|
334
437
|
fprintf(OF, "%li", stream_end - stream_start);
|
335
438
|
fclose(OF);
|
336
439
|
Free_Records(ierr);
|
337
440
|
}
|
338
441
|
|
339
|
-
|
442
|
+
|
443
|
+
void
|
444
|
+
Rename_pdf(char *oldname, char *newname)
|
340
445
|
{
|
341
446
|
char old_ofile[300], new_ofile[300];
|
342
447
|
Get_pdf_name(old_ofile, oldname, 300);
|
@@ -76,18 +76,23 @@
|
|
76
76
|
*/
|
77
77
|
|
78
78
|
|
79
|
-
void
|
79
|
+
void
|
80
|
+
Free_JPG(JPG_Info *xo)
|
80
81
|
{
|
81
82
|
if (xo->filename != NULL) free(xo->filename);
|
82
83
|
}
|
83
84
|
|
84
|
-
|
85
|
+
|
86
|
+
void
|
87
|
+
Free_Sampled(Sampled_Info *xo)
|
85
88
|
{
|
86
89
|
if (xo->image_data != NULL) free(xo->image_data);
|
87
90
|
if (xo->lookup != NULL) free(xo->lookup);
|
88
91
|
}
|
89
92
|
|
90
|
-
|
93
|
+
|
94
|
+
static bool
|
95
|
+
Is_monochrome(int obj_num)
|
91
96
|
{
|
92
97
|
XObject_Info *xo;
|
93
98
|
for (xo = xobj_list; xo != NULL; xo = xo->next) {
|
@@ -99,21 +104,32 @@ static bool Is_monochrome(int obj_num)
|
|
99
104
|
return false;
|
100
105
|
}
|
101
106
|
|
102
|
-
|
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)
|
103
111
|
{
|
104
112
|
FILE *jpg = fopen(filename, "r");
|
105
|
-
if (jpg == NULL) {
|
113
|
+
if (jpg == NULL) {
|
114
|
+
RAISE_ERROR_s("Sorry: cannot open file for showing image (%s)\n",
|
115
|
+
filename, ierr);
|
116
|
+
return;
|
117
|
+
}
|
106
118
|
unsigned char *buff;
|
107
119
|
int len, rd_len;
|
108
120
|
int buff_len = 256000;
|
109
121
|
buff = ALLOC_N_unsigned_char(buff_len);
|
110
122
|
len = 0;
|
111
|
-
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len)
|
123
|
+
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) {
|
124
|
+
len += buff_len;
|
125
|
+
}
|
112
126
|
len += rd_len;
|
113
127
|
fprintf(OF, "\t/Subtype /Image\n");
|
114
128
|
if (mask_obj_num > 0) {
|
115
|
-
if (!Is_monochrome(mask_obj_num))
|
116
|
-
|
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);
|
117
133
|
}
|
118
134
|
fprintf(OF, "\t/Width %i\n", width);
|
119
135
|
fprintf(OF, "\t/Height %i\n", height);
|
@@ -122,23 +138,32 @@ static void Write_Image_From_File(char *filename, int width, int height, char *o
|
|
122
138
|
if (len < buff_len) fwrite(buff, 1, len, OF);
|
123
139
|
else {
|
124
140
|
rewind(jpg);
|
125
|
-
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len)
|
141
|
+
while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) {
|
142
|
+
fwrite(buff, 1, buff_len, OF);
|
143
|
+
}
|
126
144
|
fwrite(buff, 1, rd_len, OF);
|
127
145
|
}
|
128
146
|
fprintf(OF, "\nendstream\n");
|
129
147
|
fclose(jpg);
|
130
148
|
}
|
131
149
|
|
132
|
-
|
150
|
+
|
151
|
+
void
|
152
|
+
Write_JPG(JPG_Info *xo, int *ierr)
|
133
153
|
{
|
134
154
|
Write_Image_From_File(xo->filename, xo->width, xo->height,
|
135
|
-
|
155
|
+
"\t/Filter /DCTDecode\n\t/ColorSpace "
|
156
|
+
"/DeviceRGB\n\t/BitsPerComponent 8\n",
|
157
|
+
xo->mask_obj_num, ierr);
|
136
158
|
}
|
137
159
|
|
138
|
-
|
160
|
+
|
161
|
+
void
|
162
|
+
Write_Sampled(Sampled_Info *xo, int *ierr)
|
139
163
|
{
|
140
164
|
fprintf(OF, "\n\t/Subtype /Image\n");
|
141
|
-
fprintf(OF, "\t/Filter /FlateDecode\n\t/Interpolate %s\n",
|
165
|
+
fprintf(OF, "\t/Filter /FlateDecode\n\t/Interpolate %s\n",
|
166
|
+
(xo->interpolate)? "true":"false");
|
142
167
|
fprintf(OF, "\t/Height %i\n", xo->height);
|
143
168
|
fprintf(OF, "\t/Width %i\n", xo->width);
|
144
169
|
int i, len;
|
@@ -177,16 +202,22 @@ void Write_Sampled(Sampled_Info *xo, int *ierr)
|
|
177
202
|
}
|
178
203
|
if (xo->mask_obj_num > 0) {
|
179
204
|
if (xo->image_type == MONO_IMAGE) {
|
180
|
-
RAISE_ERROR("Sorry: monochrome images must not have masks", ierr);
|
181
|
-
|
182
|
-
|
205
|
+
RAISE_ERROR("Sorry: monochrome images must not have masks", ierr);
|
206
|
+
return;
|
207
|
+
}
|
208
|
+
if (!Is_monochrome(xo->mask_obj_num))
|
209
|
+
fprintf(OF, "\t/SMask %i 0 R\n", xo->mask_obj_num);
|
210
|
+
else
|
211
|
+
fprintf(OF, "\t/Mask %i 0 R\n", xo->mask_obj_num);
|
183
212
|
}
|
184
|
-
if (xo->value_mask_min >= 0 && xo->value_mask_max >= 0
|
185
|
-
|
213
|
+
if (xo->value_mask_min >= 0 && xo->value_mask_max >= 0
|
214
|
+
&& xo->value_mask_min <= 255 && xo->value_mask_max <= 255
|
215
|
+
&& xo->value_mask_min <= xo->value_mask_max)
|
186
216
|
fprintf(OF, "\t/Mask [%i %i]\n", xo->value_mask_min, xo->value_mask_max);
|
187
217
|
new_len = (xo->length * 11)/10 + 100;
|
188
218
|
buffer = ALLOC_N_unsigned_char(new_len);
|
189
|
-
if (do_flate_compress(buffer, &new_len, xo->image_data, xo->length)
|
219
|
+
if (do_flate_compress(buffer, &new_len, xo->image_data, xo->length)
|
220
|
+
!= FLATE_OK) {
|
190
221
|
free(buffer);
|
191
222
|
RAISE_ERROR("Error compressing image data", ierr);
|
192
223
|
return;
|
@@ -194,25 +225,35 @@ void Write_Sampled(Sampled_Info *xo, int *ierr)
|
|
194
225
|
fprintf(OF, "\t/Length %li\n", new_len);
|
195
226
|
fprintf(OF, "\t>>\nstream\n");
|
196
227
|
if (fwrite(buffer, 1, new_len, OF) < new_len) {
|
197
|
-
RAISE_ERROR("Error writing image data", ierr);
|
228
|
+
RAISE_ERROR("Error writing image data", ierr);
|
229
|
+
return;
|
230
|
+
}
|
198
231
|
free(buffer);
|
199
232
|
fprintf(OF, "\nendstream\nendobj\n");
|
200
233
|
}
|
201
234
|
|
202
|
-
|
203
|
-
|
204
|
-
|
235
|
+
|
236
|
+
// transform maps (0,0), (1,0), and (0,1) to the given points
|
237
|
+
static void
|
238
|
+
Create_Transform_from_Points(double llx, double lly, double lrx, double lry,
|
239
|
+
double ulx, double uly, double *a, double *b,
|
240
|
+
double *c, double *d, double *e, double *f)
|
205
241
|
{
|
206
242
|
*e = llx; *f = lly; lrx -= llx; ulx -= llx; lry -= lly; uly -= lly;
|
207
243
|
*a = lrx; *b = lry; *c = ulx; *d = uly;
|
208
244
|
}
|
209
245
|
|
210
|
-
|
246
|
+
|
247
|
+
static void
|
248
|
+
Get_Image_Dest(FM *p, OBJ_PTR image_destination, double *dest, int *ierr)
|
211
249
|
{
|
212
250
|
int len = Array_Len(image_destination,ierr);
|
213
251
|
if (*ierr != 0) return;
|
214
252
|
if (len != 6) {
|
215
|
-
RAISE_ERROR("Sorry: invalid image destination array:
|
253
|
+
RAISE_ERROR("Sorry: invalid image destination array: "
|
254
|
+
"must have 6 entries", ierr);
|
255
|
+
return;
|
256
|
+
}
|
216
257
|
int i;
|
217
258
|
for (i = 0; i < 6; i++) {
|
218
259
|
OBJ_PTR entry = Array_Entry(image_destination, i, ierr);
|
@@ -225,11 +266,15 @@ static void Get_Image_Dest(FM *p, OBJ_PTR image_destination, double *dest, int *
|
|
225
266
|
}
|
226
267
|
}
|
227
268
|
|
228
|
-
|
269
|
+
|
270
|
+
static void
|
271
|
+
Show_JPEG(FM *p, char *filename, int width, int height, double *dest,
|
272
|
+
int subtype, int mask_obj_num)
|
229
273
|
{
|
230
274
|
JPG_Info *xo = (JPG_Info *)calloc(1,sizeof(JPG_Info));
|
231
275
|
xo->xobj_subtype = subtype;
|
232
|
-
double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3],
|
276
|
+
double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3],
|
277
|
+
ulx = dest[4], uly = dest[5];
|
233
278
|
double a, b, c, d, e, f; // the transform to position the image
|
234
279
|
xo->next = xobj_list;
|
235
280
|
xobj_list = (XObject_Info *)xo;
|
@@ -240,54 +285,79 @@ static void Show_JPEG(FM *p, char *filename, int width, int height, double *dest
|
|
240
285
|
xo->width = width;
|
241
286
|
xo->height = height;
|
242
287
|
xo->mask_obj_num = mask_obj_num;
|
243
|
-
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
244
|
-
|
288
|
+
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
289
|
+
&a, &b, &c, &d, &e, &f);
|
290
|
+
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
291
|
+
a, b, c, d, e, f, xo->xo_num);
|
245
292
|
update_bbox(p, llx, lly);
|
246
293
|
update_bbox(p, lrx, lry);
|
247
294
|
update_bbox(p, ulx, uly);
|
248
295
|
update_bbox(p, lrx+ulx-llx, lry+uly-lly);
|
249
296
|
}
|
250
297
|
|
251
|
-
|
252
|
-
|
298
|
+
|
299
|
+
void
|
300
|
+
c_private_show_jpg(OBJ_PTR fmkr, FM *p, char *filename,
|
301
|
+
int width, int height, OBJ_PTR image_destination,
|
302
|
+
int mask_obj_num, int *ierr)
|
303
|
+
{
|
253
304
|
double dest[6];
|
254
305
|
if (constructing_path) {
|
255
|
-
RAISE_ERROR("Sorry: must finish with current path before
|
306
|
+
RAISE_ERROR("Sorry: must finish with current path before "
|
307
|
+
"calling show_jpg", ierr);
|
308
|
+
return;
|
309
|
+
}
|
256
310
|
Get_Image_Dest(p, image_destination, dest, ierr);
|
257
311
|
if (*ierr != 0) return;
|
258
312
|
Show_JPEG(p, filename, width, height, dest, JPG_SUBTYPE, mask_obj_num);
|
259
313
|
}
|
260
314
|
|
261
|
-
|
262
|
-
|
263
|
-
|
315
|
+
|
316
|
+
OBJ_PTR
|
317
|
+
c_private_create_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR table,
|
318
|
+
int first_row, int last_row, int first_column,
|
319
|
+
int last_column, double min_val, double max_val,
|
320
|
+
int max_code, int if_below_range,
|
321
|
+
int if_above_range, int *ierr)
|
264
322
|
{
|
265
323
|
long num_cols, num_rows;
|
266
324
|
double **data = Table_Data_for_Read(table, &num_cols, &num_rows, ierr);
|
267
325
|
if (*ierr != 0) RETURN_NIL;
|
268
326
|
if (first_column < 0) first_column += num_cols;
|
269
327
|
if (first_column < 0 || first_column >= num_cols)
|
270
|
-
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
328
|
+
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
329
|
+
first_column, ierr);
|
271
330
|
if (last_column < 0) last_column += num_cols;
|
272
331
|
if (last_column < 0 || last_column >= num_cols)
|
273
|
-
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
332
|
+
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
333
|
+
last_column, ierr);
|
274
334
|
if (first_row < 0) first_row += num_rows;
|
275
335
|
if (first_row < 0 || first_row >= num_rows)
|
276
|
-
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
336
|
+
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
337
|
+
first_row, ierr);
|
277
338
|
if (last_row < 0) last_row += num_rows;
|
278
339
|
if (last_row < 0 || last_row >= num_rows)
|
279
|
-
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
340
|
+
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
341
|
+
last_row, ierr);
|
280
342
|
if (min_val >= max_val)
|
281
|
-
RAISE_ERROR_gg("Sorry: invalid range specification: min %g max %g",
|
343
|
+
RAISE_ERROR_gg("Sorry: invalid range specification: min %g max %g",
|
344
|
+
min_val, max_val, ierr);
|
282
345
|
if (max_code <= 0 || max_code > 255)
|
283
|
-
RAISE_ERROR_i("Sorry: invalid max_code specification (%i)",
|
346
|
+
RAISE_ERROR_i("Sorry: invalid max_code specification (%i)",
|
347
|
+
max_code, ierr);
|
284
348
|
if (if_below_range < 0 || if_below_range > 255)
|
285
|
-
RAISE_ERROR_i("Sorry: invalid if_below_range specification (%i)",
|
349
|
+
RAISE_ERROR_i("Sorry: invalid if_below_range specification (%i)",
|
350
|
+
if_below_range, ierr);
|
286
351
|
if (if_above_range < 0 || if_above_range > 255)
|
287
|
-
RAISE_ERROR_i("Sorry: invalid if_above_range specification (%i)",
|
288
|
-
|
352
|
+
RAISE_ERROR_i("Sorry: invalid if_above_range specification (%i)",
|
353
|
+
if_above_range, ierr);
|
354
|
+
int i, j, k;
|
355
|
+
int width = last_column - first_column + 1;
|
356
|
+
int height = last_row - first_row + 1;
|
289
357
|
int sz = width * height;
|
290
|
-
if (sz <= 0)
|
358
|
+
if (sz <= 0)
|
359
|
+
RAISE_ERROR_ii("Sorry: invalid data specification: width (%i) "
|
360
|
+
"height (%i)", width, height, ierr);
|
291
361
|
if (*ierr != 0) RETURN_NIL;
|
292
362
|
char *buff = ALLOC_N_char(sz);
|
293
363
|
for (k = 0, i = first_row; i <= last_row; i++) {
|
@@ -308,30 +378,43 @@ OBJ_PTR c_private_create_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR table,
|
|
308
378
|
}
|
309
379
|
|
310
380
|
|
311
|
-
OBJ_PTR
|
312
|
-
|
313
|
-
|
381
|
+
OBJ_PTR
|
382
|
+
c_private_create_monochrome_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR table,
|
383
|
+
int first_row, int last_row,
|
384
|
+
int first_column, int last_column,
|
385
|
+
double boundary, bool reversed,
|
386
|
+
int *ierr)
|
314
387
|
{
|
315
388
|
long num_cols, num_rows;
|
316
389
|
double **data = Table_Data_for_Read(table, &num_cols, &num_rows, ierr);
|
317
390
|
if (*ierr != 0) RETURN_NIL;
|
318
391
|
if (first_column < 0) first_column += num_cols;
|
319
392
|
if (first_column < 0 || first_column >= num_cols)
|
320
|
-
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
393
|
+
RAISE_ERROR_i("Sorry: invalid first_column specification (%i)",
|
394
|
+
first_column, ierr);
|
321
395
|
if (last_column < 0) last_column += num_cols;
|
322
396
|
if (last_column < 0 || last_column >= num_cols)
|
323
|
-
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
397
|
+
RAISE_ERROR_i("Sorry: invalid last_column specification (%i)",
|
398
|
+
last_column, ierr);
|
324
399
|
if (first_row < 0) first_row += num_rows;
|
325
400
|
if (first_row < 0 || first_row >= num_rows)
|
326
|
-
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
401
|
+
RAISE_ERROR_i("Sorry: invalid first_row specification (%i)",
|
402
|
+
first_row, ierr);
|
327
403
|
if (last_row < 0) last_row += num_rows;
|
328
404
|
if (last_row < 0 || last_row >= num_rows)
|
329
|
-
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
330
|
-
|
405
|
+
RAISE_ERROR_i("Sorry: invalid last_row specification (%i)",
|
406
|
+
last_row, ierr);
|
407
|
+
int i, j, k;
|
408
|
+
int width = last_column - first_column + 1;
|
409
|
+
int height = last_row - first_row + 1;
|
410
|
+
int bytes_per_row = (width+7)/8;
|
331
411
|
int sz = bytes_per_row * 8 * height;
|
332
|
-
if (sz <= 0)
|
412
|
+
if (sz <= 0)
|
413
|
+
RAISE_ERROR_ii("Sorry: invalid data specification: width (%i) "
|
414
|
+
"height (%i)", width, height, ierr);
|
333
415
|
if (*ierr != 0) RETURN_NIL;
|
334
|
-
// to simplify the process, do it in two stages: first get the
|
416
|
+
// to simplify the process, do it in two stages: first get the
|
417
|
+
// values and then pack the bits
|
335
418
|
char *buff = ALLOC_N_char(sz);
|
336
419
|
for (k = 0, i = first_row; i <= last_row; i++) {
|
337
420
|
double *row = data[i];
|
@@ -362,13 +445,21 @@ OBJ_PTR c_private_create_monochrome_image_data(OBJ_PTR fmkr, FM *p, OBJ_PTR tabl
|
|
362
445
|
}
|
363
446
|
|
364
447
|
|
365
|
-
OBJ_PTR
|
366
|
-
|
367
|
-
|
448
|
+
OBJ_PTR
|
449
|
+
c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
450
|
+
double lly, double lrx, double lry, double ulx,
|
451
|
+
double uly, bool interpolate, bool reversed,
|
452
|
+
int w, int h, unsigned char* data, long len,
|
453
|
+
OBJ_PTR mask_min, OBJ_PTR mask_max, OBJ_PTR hivalue,
|
454
|
+
OBJ_PTR lookup_data, int mask_obj_num, int *ierr)
|
368
455
|
{
|
369
|
-
unsigned char *lookup=NULL;
|
370
|
-
int value_mask_min = 256, value_mask_max = 256, lookup_len=0, hival=0;
|
371
|
-
if (constructing_path) {
|
456
|
+
unsigned char *lookup = NULL;
|
457
|
+
int value_mask_min = 256, value_mask_max = 256, lookup_len = 0, hival = 0;
|
458
|
+
if (constructing_path) {
|
459
|
+
RAISE_ERROR("Sorry: must finish with current path before calling "
|
460
|
+
"show_image", ierr);
|
461
|
+
RETURN_NIL;
|
462
|
+
}
|
372
463
|
if (image_type == COLORMAP_IMAGE) {
|
373
464
|
value_mask_min = Number_to_int(mask_min, ierr);
|
374
465
|
value_mask_max = Number_to_int(mask_max, ierr);
|
@@ -378,17 +469,17 @@ OBJ_PTR c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx, do
|
|
378
469
|
if (*ierr != 0) RETURN_NIL;
|
379
470
|
}
|
380
471
|
|
381
|
-
llx = convert_figure_to_output_x(p,llx);
|
382
|
-
lly = convert_figure_to_output_y(p,lly);
|
383
|
-
lrx = convert_figure_to_output_x(p,lrx);
|
384
|
-
lry = convert_figure_to_output_y(p,lry);
|
385
|
-
ulx = convert_figure_to_output_x(p,ulx);
|
386
|
-
uly = convert_figure_to_output_y(p,uly);
|
387
|
-
|
388
|
-
Sampled_Info *xo = (Sampled_Info *)calloc(1,sizeof(Sampled_Info));
|
472
|
+
llx = convert_figure_to_output_x(p, llx);
|
473
|
+
lly = convert_figure_to_output_y(p, lly);
|
474
|
+
lrx = convert_figure_to_output_x(p, lrx);
|
475
|
+
lry = convert_figure_to_output_y(p, lry);
|
476
|
+
ulx = convert_figure_to_output_x(p, ulx);
|
477
|
+
uly = convert_figure_to_output_y(p, uly);
|
478
|
+
|
479
|
+
Sampled_Info *xo = (Sampled_Info *)calloc(1, sizeof(Sampled_Info));
|
389
480
|
xo->xobj_subtype = SAMPLED_SUBTYPE;
|
390
481
|
double a, b, c, d, e, f; // the transform to position the image
|
391
|
-
int ir, ic, id;
|
482
|
+
//int ir, ic, id;
|
392
483
|
xo->next = xobj_list;
|
393
484
|
xobj_list = (XObject_Info *)xo;
|
394
485
|
xo->xo_num = next_available_xo_number++;
|
@@ -402,7 +493,9 @@ OBJ_PTR c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx, do
|
|
402
493
|
if (image_type != COLORMAP_IMAGE) xo->lookup = NULL;
|
403
494
|
else {
|
404
495
|
if ((hival+1)*3 > lookup_len) {
|
405
|
-
RAISE_ERROR_ii("Sorry: color space hival (%i) is too large for
|
496
|
+
RAISE_ERROR_ii("Sorry: color space hival (%i) is too large for "
|
497
|
+
"length of lookup table (%i)", hival, lookup_len,
|
498
|
+
ierr);
|
406
499
|
RETURN_NIL;
|
407
500
|
}
|
408
501
|
xo->hival = hival;
|
@@ -416,9 +509,13 @@ OBJ_PTR c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx, do
|
|
416
509
|
xo->value_mask_min = value_mask_min;
|
417
510
|
xo->value_mask_max = value_mask_max;
|
418
511
|
xo->mask_obj_num = mask_obj_num;
|
419
|
-
if (mask_obj_num == -1)
|
420
|
-
|
421
|
-
|
512
|
+
if (mask_obj_num == -1)
|
513
|
+
return Integer_New(xo->obj_num); // this image is being used as
|
514
|
+
// an opacity mask
|
515
|
+
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
516
|
+
&a, &b, &c, &d, &e, &f);
|
517
|
+
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
518
|
+
a, b, c, d, e, f, xo->xo_num);
|
422
519
|
update_bbox(p, llx, lly);
|
423
520
|
update_bbox(p, lrx, lry);
|
424
521
|
update_bbox(p, ulx, uly);
|