tioga 1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. data/Tioga_README +372 -0
  2. data/lgpl.txt +504 -0
  3. data/split/Dtable/defs.h +33 -0
  4. data/split/Dtable/dtable.c +1928 -0
  5. data/split/Dtable/dtable_intern.h +144 -0
  6. data/split/Dtable/dvector.h +61 -0
  7. data/split/Dtable/extconf.rb +4 -0
  8. data/split/Dtable/include/dtable.h +35 -0
  9. data/split/Dtable/lib/Dtable_extras.rb +90 -0
  10. data/split/Dtable/namespace.h +47 -0
  11. data/split/Dtable/safe_double.h +104 -0
  12. data/split/Dtable/symbols.c +92 -0
  13. data/split/Dtable/symbols.h +52 -0
  14. data/split/Dvector/defs.h +33 -0
  15. data/split/Dvector/dvector.c +5486 -0
  16. data/split/Dvector/dvector_intern.h +142 -0
  17. data/split/Dvector/extconf.rb +4 -0
  18. data/split/Dvector/include/dvector.h +61 -0
  19. data/split/Dvector/lib/Dvector_extras.rb +328 -0
  20. data/split/Dvector/lib/Numeric_extras.rb +134 -0
  21. data/split/Dvector/namespace.h +47 -0
  22. data/split/Dvector/safe_double.h +104 -0
  23. data/split/Dvector/symbols.c +92 -0
  24. data/split/Dvector/symbols.h +52 -0
  25. data/split/Flate/defs.h +33 -0
  26. data/split/Flate/extconf.rb +19 -0
  27. data/split/Flate/flate.c +156 -0
  28. data/split/Flate/flate_intern.h +97 -0
  29. data/split/Flate/include/flate.h +98 -0
  30. data/split/Flate/namespace.h +47 -0
  31. data/split/Flate/safe_double.h +104 -0
  32. data/split/Flate/symbols.c +92 -0
  33. data/split/Flate/symbols.h +52 -0
  34. data/split/Function/defs.h +33 -0
  35. data/split/Function/dvector.h +61 -0
  36. data/split/Function/extconf.rb +4 -0
  37. data/split/Function/function.c +988 -0
  38. data/split/Function/joint_qsort.c +258 -0
  39. data/split/Function/lib/Function_extras.rb +44 -0
  40. data/split/Function/namespace.h +47 -0
  41. data/split/Function/safe_double.h +104 -0
  42. data/split/Function/symbols.c +92 -0
  43. data/split/Function/symbols.h +52 -0
  44. data/split/Tioga/axes.c +774 -0
  45. data/split/Tioga/defs.h +33 -0
  46. data/split/Tioga/dtable.h +35 -0
  47. data/split/Tioga/dvector.h +61 -0
  48. data/split/Tioga/extconf.rb +4 -0
  49. data/split/Tioga/figures.c +672 -0
  50. data/split/Tioga/figures.h +855 -0
  51. data/split/Tioga/flate.h +98 -0
  52. data/split/Tioga/init.c +524 -0
  53. data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
  54. data/split/Tioga/lib/ColorConstants.rb +274 -0
  55. data/split/Tioga/lib/Colorbars.rb +10 -0
  56. data/split/Tioga/lib/Colormaps.rb +105 -0
  57. data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
  58. data/split/Tioga/lib/Creating_Paths.rb +94 -0
  59. data/split/Tioga/lib/Doc.rb +91 -0
  60. data/split/Tioga/lib/Executive.rb +515 -0
  61. data/split/Tioga/lib/FigMkr.rb +2224 -0
  62. data/split/Tioga/lib/FigureConstants.rb +125 -0
  63. data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
  64. data/split/Tioga/lib/Images.rb +278 -0
  65. data/split/Tioga/lib/Legends.rb +190 -0
  66. data/split/Tioga/lib/MarkerConstants.rb +122 -0
  67. data/split/Tioga/lib/Markers.rb +129 -0
  68. data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
  69. data/split/Tioga/lib/Rectangles.rb +94 -0
  70. data/split/Tioga/lib/Shading.rb +100 -0
  71. data/split/Tioga/lib/Special_Paths.rb +307 -0
  72. data/split/Tioga/lib/Strokes.rb +129 -0
  73. data/split/Tioga/lib/TeX_Text.rb +454 -0
  74. data/split/Tioga/lib/TexPreamble.rb +358 -0
  75. data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
  76. data/split/Tioga/lib/Transparency.rb +89 -0
  77. data/split/Tioga/lib/Using_Paths.rb +164 -0
  78. data/split/Tioga/lib/Utils.rb +74 -0
  79. data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
  80. data/split/Tioga/lib/irb_tioga.rb +122 -0
  81. data/split/Tioga/lib/tioga.rb +1 -0
  82. data/split/Tioga/lib/tioga_ui.rb +5 -0
  83. data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
  84. data/split/Tioga/makers.c +989 -0
  85. data/split/Tioga/mk_tioga_sty.rb +53 -0
  86. data/split/Tioga/namespace.h +47 -0
  87. data/split/Tioga/pdf_font_dicts.c +18253 -0
  88. data/split/Tioga/pdfcolor.c +486 -0
  89. data/split/Tioga/pdfcoords.c +505 -0
  90. data/split/Tioga/pdffile.c +342 -0
  91. data/split/Tioga/pdfimage.c +536 -0
  92. data/split/Tioga/pdfpath.c +914 -0
  93. data/split/Tioga/pdfs.h +229 -0
  94. data/split/Tioga/pdftext.c +443 -0
  95. data/split/Tioga/safe_double.h +104 -0
  96. data/split/Tioga/symbols.c +92 -0
  97. data/split/Tioga/symbols.h +52 -0
  98. data/split/Tioga/texout.c +380 -0
  99. data/split/defs.h +33 -0
  100. data/split/extconf.rb +107 -0
  101. data/split/mkmf2.rb +1612 -0
  102. data/split/namespace.h +47 -0
  103. data/split/safe_double.h +104 -0
  104. data/split/scripts/tioga +4 -0
  105. data/split/symbols.c +92 -0
  106. data/split/symbols.h +52 -0
  107. data/tests/dtable_test.data +6 -0
  108. data/tests/dvector_read_test.data +1 -0
  109. data/tests/dvector_test.data +101 -0
  110. data/tests/tc_Dtable.rb +221 -0
  111. data/tests/tc_Dvector.rb +791 -0
  112. data/tests/tc_FMkr.rb +162 -0
  113. data/tests/tc_Flate.rb +45 -0
  114. data/tests/tc_Function.rb +111 -0
  115. data/tests/ts_Tioga.rb +38 -0
  116. metadata +163 -0
@@ -0,0 +1,342 @@
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
+ char *predefined_Fonts[] = { /* must match the font numbers in FigureConstants.rb */
32
+ NULL,
33
+ "Times-Roman",
34
+ "Times-Italic", // 2
35
+ "Times-Bold",
36
+ "Times-BoldItalic",
37
+ "Helvetica",
38
+ "Helvetica-Oblique", // 6
39
+ "Helvetica-Bold",
40
+ "Helvetica-BoldOblique",
41
+ "Courier",
42
+ "Courier-Oblique", // 10
43
+ "Courier-Bold",
44
+ "Courier-BoldOblique",
45
+ "Symbol",
46
+ "ZapfDingbats" // 14
47
+ };
48
+ int num_predefined_fonts = 14;
49
+ int num_pdf_standard_fonts = 14;
50
+
51
+ long int *obj_offsets, capacity_obj_offsets, stream_start, stream_end, length_offset, xref_offset;
52
+ int num_objects, next_available_object_number, next_available_gs_number, next_available_xo_number;
53
+ int next_available_shade_number, next_available_font_number;
54
+ Stroke_Opacity_State *stroke_opacities = NULL;
55
+ Fill_Opacity_State *fill_opacities = NULL;
56
+ XObject_Info *xobj_list = NULL;
57
+ Function_Info *functions_list;
58
+ Shading_Info *shades_list = NULL;
59
+ Font_Dictionary *font_dictionaries = NULL;
60
+ Old_Font_Dictionary *old_font_dictionaries = NULL;
61
+ FILE *OF = NULL; // for the PDF file
62
+ FILE *TF = NULL; // for the temp file
63
+
64
+ /* PDF File Management */
65
+
66
+ void Free_XObjects(void)
67
+ {
68
+ XObject_Info *xo;
69
+ while (xobj_list != NULL) {
70
+ xo = xobj_list;
71
+ xobj_list = xo->next;
72
+ switch (xo->xobj_subtype) {
73
+ case JPG_SUBTYPE: Free_JPG((JPG_Info *)xo); break;
74
+ case SAMPLED_SUBTYPE: Free_Sampled((Sampled_Info *)xo); break;
75
+ default: rb_raise(rb_eArgError, "Invalid XObject subtype (%i)", xo->xobj_subtype);
76
+ }
77
+ free(xo);
78
+ }
79
+ }
80
+
81
+ void Init_pdf(void)
82
+ {
83
+ int i;
84
+ writing_file = false;
85
+ capacity_obj_offsets = 1000;
86
+ num_objects = 0;
87
+ obj_offsets = ALLOC_N(long int, capacity_obj_offsets);
88
+ for (i=0; i < capacity_obj_offsets; i++) obj_offsets[i] = 0;
89
+ }
90
+
91
+ void Record_Object_Offset(int obj_number)
92
+ {
93
+ long int offset = ftell(OF);
94
+ if (obj_number >= capacity_obj_offsets) {
95
+ int size_increment = 50, i;
96
+ REALLOC_N(obj_offsets, long int, obj_number + size_increment);
97
+ capacity_obj_offsets = obj_number + size_increment;
98
+ for (i=num_objects; i < capacity_obj_offsets; i++) obj_offsets[i] = 0;
99
+ }
100
+ obj_offsets[obj_number] = offset;
101
+ if (obj_number >= num_objects) num_objects = obj_number + 1;
102
+ }
103
+
104
+ static void Write_XObjects(void)
105
+ {
106
+ XObject_Info *xo;
107
+ for (xo = xobj_list; xo != NULL; xo = xo->next) {
108
+ Record_Object_Offset(xo->obj_num);
109
+ fprintf(OF, "%i 0 obj << /Type /XObject ", xo->obj_num);
110
+ switch (xo->xobj_subtype) {
111
+ case JPG_SUBTYPE: Write_JPG((JPG_Info *)xo); break;
112
+ case SAMPLED_SUBTYPE: Write_Sampled((Sampled_Info *)xo); break;
113
+ default: rb_raise(rb_eArgError, "Invalid XObject subtype (%i)", xo->xobj_subtype);
114
+ }
115
+ fprintf(OF, ">> endobj\n");
116
+ }
117
+ }
118
+
119
+ #define INFO_OBJ 1
120
+ #define PAGES_OBJ 2
121
+ #define STREAM_OBJ 3
122
+ #define PAGE_OBJ 4
123
+ #define CATALOG_OBJ 5
124
+ #define FIRST_OTHER_OBJ 6
125
+
126
+ static void Free_Records()
127
+ {
128
+ Free_Stroke_Opacities(); Free_Fill_Opacities(); Free_XObjects(); Free_Shadings(); Free_Functions();
129
+ }
130
+
131
+ static void Get_pdf_name(char *ofile, char *filename, int maxlen)
132
+ {
133
+ char *dot;
134
+ strncpy(ofile, filename, maxlen);
135
+ dot = strrchr(ofile,'.');
136
+ if (dot != NULL) dot[0] = '\0';
137
+ strcat(ofile, "_figure.pdf");
138
+ }
139
+
140
+ void Open_pdf(VALUE fmkr, char *filename, bool quiet_mode)
141
+ {
142
+ FM *p = Get_FM(fmkr);
143
+ int i;
144
+ if (writing_file) rb_raise(rb_eArgError, "Sorry: cannot start a new output file until finish current one.");
145
+ Clear_Fonts_In_Use_Flags();
146
+ Free_Records();
147
+ next_available_object_number = FIRST_OTHER_OBJ;
148
+ next_available_font_number = num_predefined_fonts + 1;
149
+ next_available_gs_number = 1;
150
+ next_available_xo_number = 1;
151
+ next_available_shade_number = 1;
152
+ writing_file = true;
153
+ time_t now = time(NULL);
154
+ char ofile[300], timestring[100];
155
+ Get_pdf_name(ofile, filename, 300);
156
+ if ((OF = fopen(ofile, "w")) == NULL)
157
+ rb_raise(rb_eArgError, "Sorry: can't open %s.\n", filename);
158
+ if ((TF = tmpfile()) == NULL)
159
+ rb_raise(rb_eArgError, "Sorry: can't create temp file for writing PDF file %s.\n", filename);
160
+ /* open PDF file and write header */
161
+ fprintf(OF, "%%PDF-1.4\n");
162
+ strcpy(timestring, ctime(&now));
163
+ i = strlen(timestring);
164
+ if (i > 0) timestring[i-1] = '\0';
165
+ Record_Object_Offset(INFO_OBJ);
166
+ fprintf(OF, "%i 0 obj <<\n/Creator (Tioga)\n/CreationDate (%s)\n>>\nendobj\n", INFO_OBJ, timestring);
167
+ Record_Object_Offset(PAGES_OBJ);
168
+ fprintf(OF, "%i 0 obj <<\n/Type /Pages\n/Kids [%i 0 R]\n/Count 1\n>> endobj\n", PAGES_OBJ, PAGE_OBJ);
169
+ Record_Object_Offset(STREAM_OBJ);
170
+ if (FLATE_ENCODE)
171
+ fprintf(OF, "%i 0 obj <<\t/Filter /FlateDecode /Length ", STREAM_OBJ);
172
+ else
173
+ fprintf(OF, "%i 0 obj <<\t/Length ", STREAM_OBJ);
174
+ length_offset = ftell(OF);
175
+ fprintf(OF, " \n>>\nstream\n");
176
+ stream_start = ftell(OF);
177
+ fprintf(TF, "%.2f 0 0 %.2f %.2f %.2f cm\n", 1.0/ENLARGE, 1.0/ENLARGE,
178
+ Get_pdf_xoffset(), Get_pdf_yoffset());
179
+ /* set stroke and fill colors to black */
180
+ have_current_point = constructing_path = false;
181
+ c_line_width_set(p, p->line_width);
182
+ c_line_cap_set(p, p->line_cap);
183
+ c_line_join_set(p, p->line_join);
184
+ c_miter_limit_set(p, p->miter_limit);
185
+ FM_line_type_set(fmkr, p->line_type);
186
+ FM_stroke_color_set(fmkr, p->stroke_color);
187
+ FM_fill_color_set(fmkr, p->fill_color);
188
+ // initialize clip region
189
+ bbox_llx = bbox_lly = 1e5;
190
+ bbox_urx = bbox_ury = -1e5;
191
+ }
192
+
193
+ void Start_Axis_Standard_State(FM *p, VALUE color, double line_width) {
194
+ fprintf(TF, "q 2 J [] 0 d\n");
195
+ c_line_width_set(p, line_width);
196
+ if (color != Qnil)
197
+ FM_stroke_color_set(p->fm, color);
198
+ else
199
+ fprintf(TF, "0 0 0 RG\n"); // black
200
+ /* 2 J sets the line cap style to square cap */
201
+ /* set stroke and fill colors to black. set line type to solid */
202
+ }
203
+
204
+ void End_Axis_Standard_State(void) { Write_grestore(); }
205
+
206
+ void Write_gsave(void)
207
+ {
208
+ fprintf(TF, "q\n");
209
+ }
210
+
211
+ void Write_grestore(void)
212
+ {
213
+ fprintf(TF, "Q\n");
214
+ }
215
+
216
+ void Print_Xref(long int offset) {
217
+ char line[80];
218
+ int i, len;
219
+ sprintf(line, "%li", offset);
220
+ len = strlen(line);
221
+ for (i=0; i < 10-len; i++) fputc('0', OF);
222
+ fprintf(OF, "%s 00000 n \n", line);
223
+ }
224
+
225
+ static void Write_Stream(void)
226
+ {
227
+ long int len = ftell(TF);
228
+ unsigned long int new_len = (len * 11) / 10 + 100;
229
+ unsigned char *buffer, *dest_buffer;
230
+ rewind(TF);
231
+ buffer = ALLOC_N(unsigned char, len+1);
232
+ dest_buffer = ALLOC_N(unsigned char, new_len+1);
233
+ fread(buffer, 1, len, TF);
234
+ fclose(TF);
235
+ if (FLATE_ENCODE) {
236
+ if (flate_compress(dest_buffer, &new_len, buffer, len) != FLATE_OK) {
237
+ free(buffer); free(dest_buffer);
238
+ rb_raise(rb_eArgError, "Error compressing PDF stream data");
239
+ }
240
+ fwrite(dest_buffer, 1, new_len, OF);
241
+ } else {
242
+ fwrite(buffer, 1, len, OF);
243
+ }
244
+ free(buffer); free(dest_buffer);
245
+ }
246
+
247
+ void Close_pdf(VALUE fmkr, bool quiet_mode)
248
+ {
249
+ FM *p = Get_FM(fmkr);
250
+ int i;
251
+ double llx, lly, urx, ury, xoff, yoff;
252
+ if (!writing_file) rb_raise(rb_eArgError, "Sorry: cannot End_Output if not writing file.");
253
+ writing_file = false;
254
+ if (constructing_path) rb_raise(rb_eArgError, "Sorry: must finish with current path before ending file");
255
+ Write_Stream();
256
+ stream_end = ftell(OF);
257
+ fprintf(OF, "endstream\nendobj\n");
258
+ Record_Object_Offset(PAGE_OBJ);
259
+ fprintf(OF, "%i 0 obj <<\n/Type /Page\n/Parent %i 0 R\n/MediaBox [ ", PAGE_OBJ, PAGES_OBJ);
260
+ if (bbox_llx < p->page_left) bbox_llx = p->page_left;
261
+ if (bbox_lly < p->page_bottom) bbox_lly = p->page_bottom;
262
+ if (bbox_urx > p->page_left + p->page_width) bbox_urx = p->page_left + p->page_width;
263
+ if (bbox_ury > p->page_bottom + p->page_height) bbox_ury = p->page_bottom + p->page_height;
264
+ //#define MARGIN 3
265
+ #define MARGIN 0
266
+ xoff = Get_pdf_xoffset();
267
+ yoff = Get_pdf_yoffset();
268
+ llx = bbox_llx / ENLARGE + xoff - MARGIN; // convert back to points
269
+ lly = bbox_lly / ENLARGE + yoff - MARGIN;
270
+ urx = bbox_urx / ENLARGE + xoff + MARGIN;
271
+ ury = bbox_ury / ENLARGE + yoff + MARGIN;
272
+ if (urx < llx || ury < lly) rb_raise(rb_eArgError, "Sorry: Empty plot!");
273
+ fprintf(OF, "%d %d %d %d", ROUND(llx), ROUND(lly), ROUND(urx), ROUND(ury));
274
+ fprintf(OF, " ]\n/Contents %i 0 R\n/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n", STREAM_OBJ);
275
+ if (Used_Any_Fonts()) {
276
+ Font_Dictionary *f;
277
+ fprintf(OF, " /Font <<\n ");
278
+ for (f = font_dictionaries; f != NULL; f = f->next) {
279
+ if (!f->in_use) continue;
280
+ fprintf(OF, " /F%i %i 0 R\n", f->font_num, f->obj_num);
281
+ }
282
+ fprintf(OF, " >>\n"); // end of /Font
283
+ }
284
+ if (fill_opacities != NULL || stroke_opacities != NULL) { // ExtGstate objects go here
285
+ Fill_Opacity_State *pf;
286
+ Stroke_Opacity_State *ps;
287
+ fprintf(OF, " /ExtGState <<\n");
288
+ for (ps = stroke_opacities; ps != NULL; ps = ps->next) {
289
+ fprintf(OF, " /GS%i %i 0 R\n", ps->gs_num, ps->obj_num);
290
+ }
291
+ for (pf = fill_opacities; pf != NULL; pf = pf->next) {
292
+ fprintf(OF, " /GS%i %i 0 R\n", pf->gs_num, pf->obj_num);
293
+ }
294
+ fprintf(OF, " >>\n"); // end of /ExtGState
295
+ }
296
+ if (xobj_list != NULL) { // Xobjects go here
297
+ XObject_Info *xo;
298
+ fprintf(OF, " /XObject <<\n");
299
+ for (xo = xobj_list; xo != NULL; xo = xo->next) {
300
+ fprintf(OF, " /XObj%i %i 0 R\n", xo->xo_num, xo->obj_num);
301
+ }
302
+ fprintf(OF, " >>\n"); // end of /XObject
303
+ }
304
+ if (shades_list != NULL) { // Shadings go here
305
+ Shading_Info *so;
306
+ fprintf(OF, " /Shading <<\n");
307
+ for (so = shades_list; so != NULL; so = so->next) {
308
+ fprintf(OF, " /Shade%i %i 0 R\n", so->shade_num, so->obj_num);
309
+ }
310
+ fprintf(OF, " >>\n"); // end of /Shading
311
+ }
312
+ fprintf(OF, " >>\n"); // end of /Resources
313
+ fprintf(OF, ">> endobj\n");
314
+ Record_Object_Offset(CATALOG_OBJ);
315
+ fprintf(OF, "%i 0 obj <<\n/Type /Catalog\n/Pages %i 0 R\n>> endobj\n", CATALOG_OBJ, PAGES_OBJ);
316
+ Write_Font_Dictionaries();
317
+ Write_Font_Descriptors();
318
+ Write_Font_Widths();
319
+ Write_Stroke_Opacity_Objects();
320
+ Write_Fill_Opacity_Objects();
321
+ Write_XObjects();
322
+ Write_Functions();
323
+ Write_Shadings();
324
+ xref_offset = ftell(OF);
325
+ fprintf(OF, "xref\n0 %i\n0000000000 65535 f \n", num_objects);
326
+ for (i = 1; i < num_objects; i++) Print_Xref(obj_offsets[i]); // NB: DONT USE OBJECT 0
327
+ fprintf(OF, "trailer\n<<\n/Size %i\n/Root %i 0 R\n/Info %i 0 R\n>>\nstartxref\n%li\n%%%%EOF\n",
328
+ num_objects, CATALOG_OBJ, INFO_OBJ, xref_offset);
329
+ fseek(OF, length_offset, SEEK_SET);
330
+ fprintf(OF, "%li", stream_end - stream_start);
331
+ fclose(OF);
332
+ Free_Records();
333
+ }
334
+
335
+ void Rename_pdf(char *oldname, char *newname)
336
+ {
337
+ char old_ofile[300], new_ofile[300];
338
+ Get_pdf_name(old_ofile, oldname, 300);
339
+ Get_pdf_name(new_ofile, newname, 300);
340
+ rename(old_ofile, new_ofile); // from stdio.h
341
+ }
342
+
@@ -0,0 +1,536 @@
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 Free_JPG(JPG_Info *xo)
80
+ {
81
+ if (xo->filename != NULL) free(xo->filename);
82
+ }
83
+
84
+ void Free_Sampled(Sampled_Info *xo)
85
+ {
86
+ if (xo->image_data != NULL) free(xo->image_data);
87
+ if (xo->lookup != NULL) free(xo->lookup);
88
+ }
89
+
90
+ static bool Is_monochrome(int obj_num)
91
+ {
92
+ XObject_Info *xo;
93
+ for (xo = xobj_list; xo != NULL; xo = xo->next) {
94
+ if (xo->xobj_subtype == SAMPLED_SUBTYPE && xo->obj_num == obj_num) {
95
+ Sampled_Info *p = (Sampled_Info *)xo;
96
+ return (p->image_type == MONO_IMAGE);
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+
102
+ static void Write_Image_From_File(char *filename, int width, int height, char *out_info, int mask_obj_num)
103
+ {
104
+ FILE *jpg = fopen(filename, "r");
105
+ if (jpg == NULL) rb_raise(rb_eArgError, "Sorry: cannot open file for showing image (%s)\n", filename);
106
+ unsigned char *buff;
107
+ int len, rd_len;
108
+ int buff_len = 256000;
109
+ buff = ALLOC_N(unsigned char, buff_len);
110
+ len = 0;
111
+ while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) len += buff_len;
112
+ len += rd_len;
113
+ fprintf(OF, "\t/Subtype /Image\n");
114
+ if (mask_obj_num > 0) {
115
+ if (!Is_monochrome(mask_obj_num)) fprintf(OF, "\t/SMask %i 0 R\n", mask_obj_num);
116
+ else fprintf(OF, "\t/Mask %i 0 R\n", mask_obj_num);
117
+ }
118
+ fprintf(OF, "\t/Width %i\n", width);
119
+ fprintf(OF, "\t/Height %i\n", height);
120
+ fprintf(OF, "%s", out_info);
121
+ fprintf(OF, "\t/Length %i\n\t>>\nstream\n", len);
122
+ if (len < buff_len) fwrite(buff, 1, len, OF);
123
+ else {
124
+ rewind(jpg);
125
+ while ((rd_len = fread(buff, 1, buff_len, jpg)) == buff_len) fwrite(buff, 1, buff_len, OF);
126
+ fwrite(buff, 1, rd_len, OF);
127
+ }
128
+ fprintf(OF, "\nendstream\n");
129
+ fclose(jpg);
130
+ }
131
+
132
+ void Write_JPG(JPG_Info *xo)
133
+ {
134
+ Write_Image_From_File(xo->filename, xo->width, xo->height,
135
+ "\t/Filter /DCTDecode\n\t/ColorSpace /DeviceRGB\n\t/BitsPerComponent 8\n", xo->mask_obj_num);
136
+ }
137
+
138
+ void Write_Sampled(Sampled_Info *xo)
139
+ {
140
+ fprintf(OF, "\n\t/Subtype /Image\n");
141
+ fprintf(OF, "\t/Filter /FlateDecode\n\t/Interpolate %s\n", (xo->interpolate)? "true":"false");
142
+ fprintf(OF, "\t/Height %i\n", xo->height);
143
+ fprintf(OF, "\t/Width %i\n", xo->width);
144
+ int i, len;
145
+ unsigned long new_len;
146
+ unsigned char *buffer;
147
+ switch (xo->image_type) {
148
+ case RGB_IMAGE:
149
+ fprintf(OF, "\t/ColorSpace /DeviceRGB\n");
150
+ fprintf(OF, "\t/BitsPerComponent 8\n");
151
+ break;
152
+ case CMYK_IMAGE:
153
+ fprintf(OF, "\t/ColorSpace /DeviceCMYK\n");
154
+ fprintf(OF, "\t/BitsPerComponent 8\n");
155
+ break;
156
+ case GRAY_IMAGE:
157
+ fprintf(OF, "\t/ColorSpace /DeviceGray\n");
158
+ fprintf(OF, "\t/BitsPerComponent 8\n");
159
+ break;
160
+ case MONO_IMAGE:
161
+ fprintf(OF, "\t/ImageMask true\n");
162
+ fprintf(OF, "\t/BitsPerComponent 1\n");
163
+ if (!xo->reversed) fprintf(OF, "\t/Decode [0 1]\n");
164
+ else fprintf(OF, "\t/Decode [1 0]\n");
165
+ break;
166
+ default:
167
+ len = xo->lookup_len;
168
+ fprintf(OF, "\t/ColorSpace [ /Indexed /DeviceRGB %i <", xo->hival);
169
+ for (i = 0; i < len; i++) {
170
+ unsigned char c = xo->lookup[i];
171
+ if (c == 0) fprintf(OF, "00");
172
+ else if (c < 16) fprintf(OF, "0%x", c);
173
+ else fprintf(OF, "%x", c);
174
+ }
175
+ fprintf(OF, "> ]\n");
176
+ fprintf(OF, "\t/BitsPerComponent 8\n");
177
+ }
178
+ if (xo->mask_obj_num > 0) {
179
+ if (xo->image_type == MONO_IMAGE)
180
+ rb_raise(rb_eArgError, "Sorry: monochrome images must not have masks");
181
+ if (!Is_monochrome(xo->mask_obj_num)) fprintf(OF, "\t/SMask %i 0 R\n", xo->mask_obj_num);
182
+ else fprintf(OF, "\t/Mask %i 0 R\n", xo->mask_obj_num);
183
+ }
184
+ if (xo->value_mask_min >= 0 && xo->value_mask_max >= 0 &&
185
+ xo->value_mask_min <= 255 && xo->value_mask_max <= 255 && xo->value_mask_min <= xo->value_mask_max)
186
+ fprintf(OF, "\t/Mask [%i %i]\n", xo->value_mask_min, xo->value_mask_max);
187
+ new_len = (xo->length * 11)/10 + 100;
188
+ buffer = ALLOC_N(unsigned char, new_len);
189
+ if (flate_compress(buffer, &new_len, xo->image_data, xo->length) != FLATE_OK) {
190
+ free(buffer);
191
+ rb_raise(rb_eArgError, "Error compressing image data");
192
+ }
193
+ fprintf(OF, "\t/Length %li\n", new_len);
194
+ fprintf(OF, "\t>>\nstream\n");
195
+ if (fwrite(buffer, 1, new_len, OF) < new_len)
196
+ rb_raise(rb_eArgError, "Error writing image data");
197
+ free(buffer);
198
+ fprintf(OF, "\nendstream\nendobj\n");
199
+ }
200
+
201
+ void Create_Transform_from_Points( // transform maps (0,0), (1,0), and (0,1) to the given points
202
+ double llx, double lly, double lrx, double lry, double ulx, double uly,
203
+ double *a, double *b, double *c, double *d, double *e, double *f)
204
+ {
205
+ *e = llx; *f = lly; lrx -= llx; ulx -= llx; lry -= lly; uly -= lly;
206
+ *a = lrx; *b = lry; *c = ulx; *d = uly;
207
+ }
208
+
209
+ void Get_Image_Dest(FM *p, VALUE image_destination, double *dest)
210
+ {
211
+ image_destination = rb_Array(image_destination);
212
+ if (RARRAY(image_destination)->len != 6)
213
+ rb_raise(rb_eArgError, "Sorry: invalid image destination array: must have 6 entries");
214
+ int i;
215
+ for (i = 0; i < 6; i++) {
216
+ VALUE entry = rb_ary_entry(image_destination, i);
217
+ entry = rb_Float(entry);
218
+ if (i % 2 == 0)
219
+ dest[i] = convert_figure_to_output_x(p,NUM2DBL(entry));
220
+ else
221
+ dest[i] = convert_figure_to_output_y(p,NUM2DBL(entry));
222
+ }
223
+ }
224
+
225
+ static void Show_JPEG(FM *p, char *filename, int width, int height, double *dest, int subtype, int mask_obj_num)
226
+ {
227
+ JPG_Info *xo = ALLOC(JPG_Info);
228
+ xo->xobj_subtype = subtype;
229
+ double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3], ulx = dest[4], uly = dest[5];
230
+ double a, b, c, d, e, f; // the transform to position the image
231
+ xo->next = xobj_list;
232
+ xobj_list = (XObject_Info *)xo;
233
+ xo->xo_num = next_available_xo_number++;
234
+ xo->obj_num = next_available_object_number++;
235
+ xo->filename = ALLOC_N(char, strlen(filename)+1);
236
+ strcpy(xo->filename, filename);
237
+ xo->width = width;
238
+ xo->height = height;
239
+ xo->mask_obj_num = mask_obj_num;
240
+ Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly, &a, &b, &c, &d, &e, &f);
241
+ fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n", a, b, c, d, e, f, xo->xo_num);
242
+ update_bbox(p, llx, lly);
243
+ update_bbox(p, lrx, lry);
244
+ update_bbox(p, ulx, uly);
245
+ update_bbox(p, lrx+ulx-llx, lry+uly-lly);
246
+ }
247
+
248
+ void c_show_jpg(FM *p, char *filename, int width, int height, double *dest, int mask_obj_num)
249
+ {
250
+ Show_JPEG(p, filename, width, height, dest, JPG_SUBTYPE, mask_obj_num);
251
+ }
252
+
253
+ VALUE FM_private_show_jpg(VALUE fmkr, VALUE filename, VALUE width, VALUE height, VALUE image_destination, VALUE mask_obj_num)
254
+ {
255
+ double dest[6];
256
+ FM *p = Get_FM(fmkr);
257
+ if (constructing_path) rb_raise(rb_eArgError, "Sorry: must finish with current path before calling show_jpg");
258
+ Get_Image_Dest(p, image_destination, dest);
259
+ width = rb_Integer(width);
260
+ height = rb_Integer(height);
261
+ mask_obj_num = rb_Integer(mask_obj_num);
262
+ filename = rb_String(filename);
263
+ c_show_jpg(p, RSTRING(filename)->ptr, NUM2INT(width), NUM2INT(height), dest, NUM2INT(mask_obj_num));
264
+ return fmkr;
265
+ }
266
+
267
+ VALUE c_private_create_image_data(FM *p, double **data, long num_cols, long num_rows,
268
+ int first_row, int last_row, int first_column, int last_column,
269
+ double min_value, double max_value, int max_code, int if_below_range, int if_above_range)
270
+ {
271
+ if (first_column < 0) first_column += num_cols;
272
+ if (first_column < 0 || first_column >= num_cols)
273
+ rb_raise(rb_eArgError, "Sorry: invalid first_column specification (%i)", first_column);
274
+ if (last_column < 0) last_column += num_cols;
275
+ if (last_column < 0 || last_column >= num_cols)
276
+ rb_raise(rb_eArgError, "Sorry: invalid last_column specification (%i)", last_column);
277
+ if (first_row < 0) first_row += num_rows;
278
+ if (first_row < 0 || first_row >= num_rows)
279
+ rb_raise(rb_eArgError, "Sorry: invalid first_row specification (%i)", first_row);
280
+ if (last_row < 0) last_row += num_rows;
281
+ if (last_row < 0 || last_row >= num_rows)
282
+ rb_raise(rb_eArgError, "Sorry: invalid last_row specification (%i)", last_row);
283
+ if (min_value >= max_value)
284
+ rb_raise(rb_eArgError, "Sorry: invalid range specification: min %g max %g", min_value, max_value);
285
+ if (max_code <= 0 || max_code > 255)
286
+ rb_raise(rb_eArgError, "Sorry: invalid max_code specification (%i)", max_code);
287
+ if (if_below_range < 0 || if_below_range > 255)
288
+ rb_raise(rb_eArgError, "Sorry: invalid if_below_range specification (%i)", if_below_range);
289
+ if (if_above_range < 0 || if_above_range > 255)
290
+ rb_raise(rb_eArgError, "Sorry: invalid if_above_range specification (%i)", if_above_range);
291
+ int i, j, k, width = last_column - first_column + 1, height = last_row - first_row + 1;
292
+ int sz = width * height;
293
+ if (sz <= 0) rb_raise(rb_eArgError, "Sorry: invalid data specification: width (%i) height (%i)", width, height);
294
+ char *buff = ALLOC_N(char, sz);
295
+ for (k = 0, i = first_row; i <= last_row; i++) {
296
+ double *row = data[i];
297
+ for (j = first_column; j <= last_column; j++) {
298
+ double val = row[j];
299
+ if (val < min_value) buff[k++] = if_below_range;
300
+ else if (val > max_value) buff[k++] = if_above_range;
301
+ else {
302
+ val = max_code * (val - min_value)/(max_value - min_value);
303
+ buff[k++] = ROUND(val);
304
+ }
305
+ }
306
+ }
307
+ VALUE result = rb_str_new(buff, sz);
308
+ free(buff);
309
+ return result;
310
+ }
311
+
312
+ VALUE FM_private_create_image_data(VALUE fmkr, VALUE data,
313
+ VALUE first_row, VALUE last_row, VALUE first_column, VALUE last_column,
314
+ VALUE min_value, VALUE max_value, VALUE max_code, VALUE if_below_range, VALUE if_above_range)
315
+ {
316
+ FM *p = Get_FM(fmkr);
317
+ long num_cols, num_rows;
318
+ double **ary = Dtable_Ptr(data, &num_cols, &num_rows);
319
+ first_row = rb_Integer(first_row);
320
+ last_row = rb_Integer(last_row);
321
+ first_column = rb_Integer(first_column);
322
+ last_column = rb_Integer(last_column);
323
+ max_code = rb_Integer(max_code);
324
+ if_below_range = rb_Integer(if_below_range);
325
+ if_above_range = rb_Integer(if_above_range);
326
+ min_value = rb_Float(min_value);
327
+ max_value = rb_Float(max_value);
328
+ return c_private_create_image_data(p, ary, num_cols, num_rows,
329
+ NUM2INT(first_row), NUM2INT(last_row), NUM2INT(first_column), NUM2INT(last_column),
330
+ NUM2DBL(min_value), NUM2DBL(max_value), NUM2INT(max_code), NUM2INT(if_below_range), NUM2INT(if_above_range));
331
+ }
332
+
333
+ static VALUE c_private_create_monochrome_image_data(FM *p, double **data, long num_cols, long num_rows,
334
+ int first_row, int last_row, int first_column, int last_column,
335
+ double boundary, bool reversed)
336
+ {
337
+ if (first_column < 0) first_column += num_cols;
338
+ if (first_column < 0 || first_column >= num_cols)
339
+ rb_raise(rb_eArgError, "Sorry: invalid first_column specification (%i)", first_column);
340
+ if (last_column < 0) last_column += num_cols;
341
+ if (last_column < 0 || last_column >= num_cols)
342
+ rb_raise(rb_eArgError, "Sorry: invalid last_column specification (%i)", last_column);
343
+ if (first_row < 0) first_row += num_rows;
344
+ if (first_row < 0 || first_row >= num_rows)
345
+ rb_raise(rb_eArgError, "Sorry: invalid first_row specification (%i)", first_row);
346
+ if (last_row < 0) last_row += num_rows;
347
+ if (last_row < 0 || last_row >= num_rows)
348
+ rb_raise(rb_eArgError, "Sorry: invalid last_row specification (%i)", last_row);
349
+ int i, j, k, width = last_column - first_column + 1, height = last_row - first_row + 1, bytes_per_row = (width+7)/8;
350
+ int sz = bytes_per_row * 8 * height;
351
+ if (sz <= 0) rb_raise(rb_eArgError, "Sorry: invalid data specification: width (%i) height (%i)", width, height);
352
+ // to simplify the process, do it in two stages: first get the values and then pack the bits
353
+ char *buff = ALLOC_N(char, sz);
354
+ for (k = 0, i = first_row; i <= last_row; i++) {
355
+ double *row = data[i];
356
+ for (j = first_column; j <= last_column; j++) {
357
+ double val = row[j];
358
+ buff[k++] = (reversed)? (val <= boundary) : (val > boundary);
359
+ }
360
+ for (j = last_column+1; j < bytes_per_row * 8; j++) {
361
+ buff[k++] = 0;
362
+ }
363
+ }
364
+ int num_bytes = (sz+7) >> 3;
365
+ char *bits = ALLOC_N(char, num_bytes), c = 0;
366
+ int num_bits = num_bytes << 3;
367
+ for (i = 0, k = -1; i < num_bits; i++) {
368
+ int bit = (i < sz)? buff[i] : 0;
369
+ int which_bit = i & 7;
370
+ if (which_bit != 0) c |= bit << (7-which_bit);
371
+ else {
372
+ if (k >= 0) bits[k] = c;
373
+ k++; c = bit << 7;
374
+ }
375
+ }
376
+ bits[k] = c;
377
+ VALUE result = rb_str_new(bits, num_bytes);
378
+ free(bits); free(buff);
379
+ return result;
380
+ }
381
+
382
+ VALUE FM_private_create_monochrome_image_data(VALUE fmkr, VALUE data,
383
+ VALUE first_row, VALUE last_row, VALUE first_column, VALUE last_column,
384
+ VALUE boundary, VALUE reverse)
385
+ {
386
+ FM *p = Get_FM(fmkr);
387
+ long num_cols, num_rows;
388
+ double **ary = Dtable_Ptr(data, &num_cols, &num_rows);
389
+ first_row = rb_Integer(first_row);
390
+ last_row = rb_Integer(last_row);
391
+ first_column = rb_Integer(first_column);
392
+ last_column = rb_Integer(last_column);
393
+ boundary = rb_Float(boundary);
394
+ return c_private_create_monochrome_image_data(p, ary, num_cols, num_rows,
395
+ NUM2INT(first_row), NUM2INT(last_row), NUM2INT(first_column), NUM2INT(last_column),
396
+ NUM2DBL(boundary), reverse != Qfalse);
397
+ }
398
+
399
+ int c_private_show_image(FM *p, int image_type, double *dest, bool interpolate, bool reversed, int w, int h, unsigned char* data, int len,
400
+ int value_mask_min, int value_mask_max, int hival, unsigned char* lookup, int lookup_len, int mask_obj_num)
401
+ {
402
+ Sampled_Info *xo = ALLOC(Sampled_Info);
403
+ xo->xobj_subtype = SAMPLED_SUBTYPE;
404
+ double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3], ulx = dest[4], uly = dest[5];
405
+ double a, b, c, d, e, f; // the transform to position the image
406
+ int ir, ic, id;
407
+ xo->next = xobj_list;
408
+ xobj_list = (XObject_Info *)xo;
409
+ xo->xo_num = next_available_xo_number++;
410
+ xo->obj_num = next_available_object_number++;
411
+ xo->image_data = ALLOC_N(unsigned char, len);
412
+ xo->length = len;
413
+ xo->interpolate = interpolate;
414
+ xo->reversed = reversed;
415
+ MEMCPY(xo->image_data, data, unsigned char, len);
416
+ xo->image_type = image_type;
417
+ if (image_type != COLORMAP_IMAGE) xo->lookup = NULL;
418
+ else {
419
+ if ((hival+1)*3 > lookup_len)
420
+ rb_raise(rb_eArgError, "Sorry: color space hival (%i) is too large for length of lookup table (%i)", hival, lookup_len);
421
+ xo->hival = hival;
422
+ lookup_len = (hival+1) * 3;
423
+ xo->lookup = ALLOC_N(unsigned char, lookup_len);
424
+ xo->lookup_len = lookup_len;
425
+ MEMCPY(xo->lookup, lookup, unsigned char, lookup_len);
426
+ }
427
+ xo->width = w;
428
+ xo->height = h;
429
+
430
+ if (0) {
431
+ printf("len=%i w=%i h=%i\ndata\n\n", len, w, h);
432
+ for (ir=0; ir<h; ir++) {
433
+ for (ic=0; ic<w; ic++) {
434
+ id = (int)data[ir*h+ic];
435
+ printf("%3i ",id);
436
+ }
437
+ printf("\n");
438
+ }
439
+
440
+
441
+ printf("\n\nxo->image_data\n");
442
+ for (ir=0; ir<h; ir++) {
443
+ for (ic=0; ic<w; ic++) {
444
+ id = (int)xo->image_data[ir*h+ic];
445
+ printf("%3i ",id);
446
+ }
447
+ printf("\n\n");
448
+ }
449
+ }
450
+
451
+
452
+ xo->value_mask_min = value_mask_min;
453
+ xo->value_mask_max = value_mask_max;
454
+ xo->mask_obj_num = mask_obj_num;
455
+ if (mask_obj_num == -1) return xo->obj_num; // this image is being used as an opacity mask
456
+ Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly, &a, &b, &c, &d, &e, &f);
457
+ fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n", a, b, c, d, e, f, xo->xo_num);
458
+ update_bbox(p, llx, lly);
459
+ update_bbox(p, lrx, lry);
460
+ update_bbox(p, ulx, uly);
461
+ update_bbox(p, lrx+ulx-llx, lry+uly-lly);
462
+ return xo->obj_num;
463
+ }
464
+
465
+ static VALUE private_show_image(int image_type, VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
466
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE reversed, VALUE w, VALUE h, VALUE data, VALUE value_mask_min, VALUE value_mask_max,
467
+ VALUE hival, VALUE lookup, VALUE mask_obj_num)
468
+ {
469
+ double dest[6];
470
+ unsigned char *lookup_str=NULL;
471
+ int mask_min = 256, mask_max = 256, lookup_len=0, hivalue=0;
472
+ FM *p = Get_FM(fmkr);
473
+ if (constructing_path) rb_raise(rb_eArgError, "Sorry: must finish with current path before calling show_image");
474
+ data = rb_String(data);
475
+ llx = rb_Float(llx);
476
+ lly = rb_Float(lly);
477
+ lrx = rb_Float(lrx);
478
+ lry = rb_Float(lry);
479
+ ulx = rb_Float(ulx);
480
+ uly = rb_Float(uly);
481
+ w = rb_Integer(w);
482
+ h = rb_Integer(h);
483
+ mask_obj_num = rb_Integer(mask_obj_num);
484
+ if (image_type == COLORMAP_IMAGE) {
485
+ value_mask_min = rb_Integer(value_mask_min); mask_min = NUM2INT(value_mask_min);
486
+ value_mask_max = rb_Integer(value_mask_max); mask_max = NUM2INT(value_mask_max);
487
+ hival = rb_Integer(hival);
488
+ hivalue = NUM2INT(hival);
489
+ lookup = rb_String(lookup);
490
+ lookup_str = (unsigned char *)(RSTRING(lookup)->ptr);
491
+ lookup_len = RSTRING(lookup)->len;
492
+ }
493
+ dest[0] = convert_figure_to_output_x(p,NUM2DBL(llx));
494
+ dest[1] = convert_figure_to_output_y(p,NUM2DBL(lly));
495
+ dest[2] = convert_figure_to_output_x(p,NUM2DBL(lrx));
496
+ dest[3] = convert_figure_to_output_y(p,NUM2DBL(lry));
497
+ dest[4] = convert_figure_to_output_x(p,NUM2DBL(ulx));
498
+ dest[5] = convert_figure_to_output_y(p,NUM2DBL(uly));
499
+ int obj_num = c_private_show_image(p, image_type, dest, (interpolate != Qfalse), (reversed == Qtrue), NUM2INT(w), NUM2INT(h),
500
+ (unsigned char *)RSTRING(data)->ptr, RSTRING(data)->len, mask_min, mask_max, hivalue, lookup_str, lookup_len, NUM2INT(mask_obj_num));
501
+ return INT2FIX(obj_num);
502
+ }
503
+
504
+ VALUE FM_private_show_rgb_image(VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
505
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE w, VALUE h, VALUE data, VALUE mask_obj_num)
506
+ {
507
+ return private_show_image(RGB_IMAGE, fmkr, llx, lly, lrx, lry, ulx, uly, interpolate, Qfalse, w, h, data, Qnil, Qnil, Qnil, Qnil, mask_obj_num);
508
+ }
509
+
510
+ VALUE FM_private_show_cmyk_image(VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
511
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE w, VALUE h, VALUE data, VALUE mask_obj_num)
512
+ {
513
+ return private_show_image(CMYK_IMAGE, fmkr, llx, lly, lrx, lry, ulx, uly, interpolate, Qfalse, w, h, data, Qnil, Qnil, Qnil, Qnil, mask_obj_num);
514
+ }
515
+
516
+ VALUE FM_private_show_grayscale_image(VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
517
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE w, VALUE h, VALUE data, VALUE mask_obj_num)
518
+ {
519
+ return private_show_image(GRAY_IMAGE, fmkr, llx, lly, lrx, lry, ulx, uly, interpolate, Qfalse, w, h, data, Qnil, Qnil, Qnil, Qnil, mask_obj_num);
520
+ }
521
+
522
+ VALUE FM_private_show_monochrome_image(VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
523
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE reversed, VALUE w, VALUE h, VALUE data, VALUE mask_obj_num)
524
+ {
525
+ return private_show_image(MONO_IMAGE, fmkr, llx, lly, lrx, lry, ulx, uly, interpolate, reversed,
526
+ w, h, data, Qnil, Qnil, Qnil, Qnil, mask_obj_num);
527
+ }
528
+
529
+ VALUE FM_private_show_image(VALUE fmkr, VALUE llx, VALUE lly, VALUE lrx, VALUE lry,
530
+ VALUE ulx, VALUE uly, VALUE interpolate, VALUE w, VALUE h, VALUE data,
531
+ VALUE value_mask_min, VALUE value_mask_max, VALUE hival, VALUE lookup, VALUE mask_obj_num)
532
+ {
533
+ return private_show_image(COLORMAP_IMAGE, fmkr, llx, lly, lrx, lry, ulx, uly, interpolate, Qfalse, w, h, data,
534
+ value_mask_min, value_mask_max, hival, lookup, mask_obj_num);
535
+ }
536
+