tioga 1.4

Sign up to get free protection for your applications and to get access to all the features.
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
+