tioga 1.11 → 1.13

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 (148) hide show
  1. data/Tioga_README +58 -35
  2. data/{split/scripts → bin}/tioga +1 -1
  3. data/{split → ext/Dobjects}/Dtable/dtable.c +81 -15
  4. data/{split → ext/Dobjects}/Dtable/dtable_intern.h +0 -0
  5. data/ext/Dobjects/Dtable/extconf.rb +7 -0
  6. data/{split → ext/Dobjects}/Dtable/include/dtable.h +0 -0
  7. data/{split → ext/Dobjects}/Dvector/dvector.c +361 -51
  8. data/{split → ext/Dobjects}/Dvector/dvector_intern.h +0 -0
  9. data/ext/Dobjects/Dvector/extconf.rb +22 -0
  10. data/{split/Dtable → ext/Dobjects/Dvector/include}/dvector.h +0 -0
  11. data/ext/Dobjects/Function/extconf.rb +7 -0
  12. data/{split → ext/Dobjects}/Function/function.c +636 -11
  13. data/{split → ext/Dobjects}/Function/joint_qsort.c +0 -0
  14. data/ext/Flate/extconf.rb +26 -0
  15. data/{split → ext}/Flate/flate.c +7 -3
  16. data/{split → ext}/Flate/flate_intern.h +0 -0
  17. data/{split → ext}/Flate/include/flate.h +0 -0
  18. data/ext/Flate/zlib/adler32.c +149 -0
  19. data/ext/Flate/zlib/compress.c +79 -0
  20. data/ext/Flate/zlib/crc32.c +423 -0
  21. data/ext/Flate/zlib/crc32.h +441 -0
  22. data/ext/Flate/zlib/deflate.c +1736 -0
  23. data/ext/Flate/zlib/deflate.h +331 -0
  24. data/ext/Flate/zlib/gzio.c +1026 -0
  25. data/ext/Flate/zlib/infback.c +623 -0
  26. data/ext/Flate/zlib/inffast.c +318 -0
  27. data/ext/Flate/zlib/inffast.h +11 -0
  28. data/ext/Flate/zlib/inffixed.h +94 -0
  29. data/ext/Flate/zlib/inflate.c +1368 -0
  30. data/ext/Flate/zlib/inflate.h +115 -0
  31. data/ext/Flate/zlib/inftrees.c +329 -0
  32. data/ext/Flate/zlib/inftrees.h +55 -0
  33. data/ext/Flate/zlib/trees.c +1219 -0
  34. data/ext/Flate/zlib/trees.h +128 -0
  35. data/ext/Flate/zlib/uncompr.c +61 -0
  36. data/ext/Flate/zlib/zlib.h +1357 -0
  37. data/ext/Flate/zlib/zutil.c +318 -0
  38. data/ext/Flate/zlib/zutil.h +269 -0
  39. data/ext/Tioga/FigureMaker/__shared_axes.c +1373 -0
  40. data/ext/Tioga/FigureMaker/__shared_makers.c +1303 -0
  41. data/{split/Tioga/pdf_font_dicts.c → ext/Tioga/FigureMaker/__shared_pdf_font_dicts.c} +0 -0
  42. data/{split/Tioga/pdfcolor.c → ext/Tioga/FigureMaker/__shared_pdfcolor.c} +0 -0
  43. data/{split/Tioga/pdfcoords.c → ext/Tioga/FigureMaker/__shared_pdfcoords.c} +0 -0
  44. data/{split/Tioga/pdffile.c → ext/Tioga/FigureMaker/__shared_pdffile.c} +0 -0
  45. data/{split/Tioga/pdfimage.c → ext/Tioga/FigureMaker/__shared_pdfimage.c} +0 -0
  46. data/{split/Tioga/pdfpath.c → ext/Tioga/FigureMaker/__shared_pdfpath.c} +0 -0
  47. data/{split/Tioga/pdftext.c → ext/Tioga/FigureMaker/__shared_pdftext.c} +0 -0
  48. data/{split/Tioga/texout.c → ext/Tioga/FigureMaker/__shared_texout.c} +0 -0
  49. data/ext/Tioga/FigureMaker/extconf.rb +7 -0
  50. data/{split/Tioga → ext/Tioga/FigureMaker}/figures.c +14 -2
  51. data/{split/Tioga → ext/Tioga/FigureMaker}/figures.h +0 -0
  52. data/{split/Tioga → ext/Tioga/FigureMaker}/generic.c +1 -2
  53. data/{split/Tioga → ext/Tioga/FigureMaker}/generic.h +0 -1
  54. data/{split/Tioga → ext/Tioga/FigureMaker}/init.c +0 -0
  55. data/{split/Tioga → ext/Tioga/FigureMaker}/pdfs.h +0 -0
  56. data/{split/Tioga → ext/Tioga/FigureMaker/shared}/axes.c +32 -7
  57. data/{split/Tioga → ext/Tioga/FigureMaker/shared}/makers.c +2 -2
  58. data/ext/Tioga/FigureMaker/shared/pdf_font_dicts.c +18253 -0
  59. data/ext/Tioga/FigureMaker/shared/pdfcolor.c +904 -0
  60. data/ext/Tioga/FigureMaker/shared/pdfcoords.c +518 -0
  61. data/ext/Tioga/FigureMaker/shared/pdffile.c +451 -0
  62. data/ext/Tioga/FigureMaker/shared/pdfimage.c +539 -0
  63. data/ext/Tioga/FigureMaker/shared/pdfpath.c +766 -0
  64. data/ext/Tioga/FigureMaker/shared/pdftext.c +710 -0
  65. data/ext/Tioga/FigureMaker/shared/texout.c +533 -0
  66. data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.c +5 -5
  67. data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.h +0 -0
  68. data/{split/Dtable → ext/includes}/defs.h +0 -0
  69. data/{split/Dtable → ext/includes}/namespace.h +0 -0
  70. data/{split/Dtable → ext/includes}/safe_double.h +0 -0
  71. data/{split → ext/includes}/symbols.c +0 -1
  72. data/{split/Dtable → ext/includes}/symbols.h +0 -0
  73. data/{split/Dtable/lib → lib/Dobjects}/Dtable_extras.rb +0 -0
  74. data/{split/Dvector/lib → lib/Dobjects}/Dvector_extras.rb +1 -0
  75. data/{split/Function/lib → lib/Dobjects}/Function_extras.rb +0 -0
  76. data/{split/Dvector/lib → lib/Dobjects}/Numeric_extras.rb +0 -0
  77. data/{split/Tioga/lib → lib/Tioga}/Arcs_and_Circles.rb +0 -0
  78. data/{split/Tioga/lib → lib/Tioga}/ColorConstants.rb +0 -0
  79. data/{split/Tioga/lib → lib/Tioga}/Colorbars.rb +0 -0
  80. data/{split/Tioga/lib → lib/Tioga}/Colormaps.rb +0 -0
  81. data/{split/Tioga/lib → lib/Tioga}/Coordinate_Conversions.rb +0 -0
  82. data/{split/Tioga/lib → lib/Tioga}/Creating_Paths.rb +0 -0
  83. data/{split/Tioga/lib → lib/Tioga}/Doc.rb +0 -0
  84. data/{split/Tioga/lib → lib/Tioga}/Executive.rb +0 -0
  85. data/{split/Tioga/lib → lib/Tioga}/FigMkr.rb +13 -70
  86. data/{split/Tioga/lib → lib/Tioga}/FigureConstants.rb +0 -0
  87. data/{split/Tioga/lib → lib/Tioga}/Figures_and_Plots.rb +0 -0
  88. data/{split/Tioga/lib → lib/Tioga}/Images.rb +0 -0
  89. data/{split/Tioga/lib → lib/Tioga}/Legends.rb +0 -0
  90. data/{split/Tioga/lib → lib/Tioga}/MarkerConstants.rb +0 -0
  91. data/{split/Tioga/lib → lib/Tioga}/Markers.rb +0 -0
  92. data/{split/Tioga/lib → lib/Tioga}/Page_Frame_Bounds.rb +0 -0
  93. data/{split/Tioga/lib → lib/Tioga}/Rectangles.rb +0 -0
  94. data/{split/Tioga/lib → lib/Tioga}/Shading.rb +0 -0
  95. data/{split/Tioga/lib → lib/Tioga}/Special_Paths.rb +0 -0
  96. data/{split/Tioga/lib → lib/Tioga}/Strokes.rb +0 -0
  97. data/{split/Tioga/lib → lib/Tioga}/TeX_Text.rb +0 -0
  98. data/{split/Tioga/lib → lib/Tioga}/TexPreamble.rb +0 -0
  99. data/{split/Tioga/lib → lib/Tioga}/Titles_and_Labels.rb +0 -0
  100. data/{split/Tioga/lib → lib/Tioga}/Transparency.rb +0 -0
  101. data/{split/Tioga/lib → lib/Tioga}/Using_Paths.rb +0 -0
  102. data/{split/Tioga/lib → lib/Tioga}/Utils.rb +74 -0
  103. data/{split/Tioga/lib → lib/Tioga}/X_and_Y_Axes.rb +0 -0
  104. data/{split/Tioga/lib → lib/Tioga}/irb_tioga.rb +0 -0
  105. data/{split/Tioga/lib → lib/Tioga}/maker.rb +0 -0
  106. data/{split/Tioga/lib → lib/Tioga}/tioga.rb +0 -0
  107. data/{split/Tioga/lib → lib/Tioga}/tioga_ui.rb +0 -0
  108. data/{split/Tioga/lib → lib/Tioga}/tioga_ui_cmds.rb +0 -0
  109. data/tests/Icon_Test.pdf +0 -0
  110. data/tests/benchmark_dvector_reads.rb +20 -42
  111. data/tests/tc_Dvector.rb +45 -4
  112. data/tests/tc_Flate.rb +4 -5
  113. data/tests/tc_Function.rb +79 -0
  114. data/tests/vg.log +1453 -0
  115. metadata +141 -122
  116. data/split/Dtable/extconf.rb +0 -4
  117. data/split/Dvector/defs.h +0 -39
  118. data/split/Dvector/extconf.rb +0 -4
  119. data/split/Dvector/include/dvector.h +0 -77
  120. data/split/Dvector/namespace.h +0 -59
  121. data/split/Dvector/safe_double.h +0 -104
  122. data/split/Dvector/symbols.h +0 -52
  123. data/split/Flate/defs.h +0 -39
  124. data/split/Flate/extconf.rb +0 -19
  125. data/split/Flate/namespace.h +0 -59
  126. data/split/Flate/safe_double.h +0 -104
  127. data/split/Flate/symbols.h +0 -52
  128. data/split/Function/defs.h +0 -39
  129. data/split/Function/dvector.h +0 -77
  130. data/split/Function/extconf.rb +0 -4
  131. data/split/Function/namespace.h +0 -59
  132. data/split/Function/safe_double.h +0 -104
  133. data/split/Function/symbols.h +0 -52
  134. data/split/Tioga/defs.h +0 -39
  135. data/split/Tioga/dtable.h +0 -35
  136. data/split/Tioga/dvector.h +0 -77
  137. data/split/Tioga/extconf.rb +0 -4
  138. data/split/Tioga/flate.h +0 -98
  139. data/split/Tioga/mk_tioga_sty.rb +0 -53
  140. data/split/Tioga/namespace.h +0 -59
  141. data/split/Tioga/safe_double.h +0 -104
  142. data/split/Tioga/symbols.h +0 -52
  143. data/split/defs.h +0 -39
  144. data/split/extconf.rb +0 -125
  145. data/split/mkmf2.rb +0 -1623
  146. data/split/namespace.h +0 -59
  147. data/split/safe_double.h +0 -104
  148. data/split/symbols.h +0 -52
@@ -0,0 +1,904 @@
1
+ /* pdfcolor.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
+
26
+ /* functions */
27
+
28
+ void
29
+ Free_Functions()
30
+ {
31
+ Function_Info *fo;
32
+ while (functions_list != NULL) {
33
+ fo = functions_list;
34
+ functions_list = fo->next;
35
+ if (fo->lookup != NULL) free(fo->lookup);
36
+ free(fo);
37
+ }
38
+ }
39
+
40
+
41
+ static void
42
+ Write_Sampled_Function(Function_Info *fo, int *ierr)
43
+ {
44
+ fprintf(OF, "%i 0 obj << /FunctionType 0\n", fo->obj_num);
45
+ fprintf(OF, "\t/Domain [0 1]\n");
46
+ fprintf(OF, "\t/Range [0 1 0 1 0 1]\n");
47
+ fprintf(OF, "\t/Size [%i]\n", fo->hival + 1);
48
+ fprintf(OF, "\t/BitsPerSample 8\n");
49
+ fprintf(OF, "\t/Order 1\n");
50
+ fprintf(OF, "\t/Length %i\n\t>>\nstream\n", fo->lookup_len);
51
+ if (fwrite(fo->lookup, 1, fo->lookup_len, OF) < fo->lookup_len) {
52
+ RAISE_ERROR("Error writing function sample data", ierr);
53
+ return;
54
+ }
55
+ fprintf(OF, "\nendstream\nendobj\n");
56
+ }
57
+
58
+
59
+ void
60
+ Write_Functions(int *ierr)
61
+ {
62
+ Function_Info *fo;
63
+ for (fo = functions_list; fo != NULL; fo = fo->next) {
64
+ Record_Object_Offset(fo->obj_num);
65
+ Write_Sampled_Function(fo, ierr);
66
+ }
67
+ }
68
+
69
+
70
+ static int
71
+ create_function(int hival, int lookup_len, unsigned char *lookup)
72
+ {
73
+ Function_Info *fo = (Function_Info *)calloc(1,sizeof(Function_Info));
74
+ fo->next = functions_list;
75
+ functions_list = fo;
76
+ fo->lookup = ALLOC_N_unsigned_char(lookup_len);
77
+ memcpy(fo->lookup, lookup, lookup_len);
78
+ fo->lookup_len = lookup_len;
79
+ fo->hival = hival;
80
+ fo->obj_num = next_available_object_number++;
81
+ return fo->obj_num;
82
+ }
83
+
84
+
85
+ /* Opacity */
86
+
87
+ void
88
+ Free_Stroke_Opacities(void)
89
+ {
90
+ Stroke_Opacity_State *p;
91
+ while (stroke_opacities != NULL) {
92
+ p = stroke_opacities;
93
+ stroke_opacities = p->next;
94
+ free(p);
95
+ }
96
+ }
97
+
98
+
99
+ static int
100
+ Get_Stroke_Opacity_XGS(double stroke_opacity)
101
+ {
102
+ Stroke_Opacity_State *p;
103
+ for (p = stroke_opacities; p != NULL; p = p->next) {
104
+ if (p->stroke_opacity == stroke_opacity) return p->gs_num;
105
+ }
106
+ p = (Stroke_Opacity_State *)calloc(1, sizeof(Stroke_Opacity_State));
107
+ p->stroke_opacity = stroke_opacity;
108
+ p->gs_num = next_available_gs_number++;
109
+ p->obj_num = next_available_object_number++;
110
+ p->next = stroke_opacities;
111
+ stroke_opacities = p;
112
+ return p->gs_num;
113
+ }
114
+
115
+
116
+ void
117
+ c_stroke_opacity_set(OBJ_PTR fmkr, FM *p, double stroke_opacity, int *ierr)
118
+ { // /GSi gs for ExtGState obj with /CS set to stroke opacity val
119
+ if (constructing_path) {
120
+ RAISE_ERROR("Sorry: must not be constructing a path when change stroke"
121
+ " opacity", ierr);
122
+ return;
123
+ }
124
+ if (stroke_opacity == p->stroke_opacity) return;
125
+ int gs_num = Get_Stroke_Opacity_XGS(stroke_opacity);
126
+ fprintf(TF, "/GS%i gs\n", gs_num);
127
+ p->stroke_opacity = stroke_opacity;
128
+ }
129
+
130
+
131
+ void
132
+ Free_Fill_Opacities(void)
133
+ {
134
+ Fill_Opacity_State *p;
135
+ while (fill_opacities != NULL) {
136
+ p = fill_opacities;
137
+ fill_opacities = p->next;
138
+ free(p);
139
+ }
140
+ }
141
+
142
+
143
+ static int
144
+ Get_Fill_Opacity_XGS(double fill_opacity)
145
+ {
146
+ Fill_Opacity_State *p;
147
+ for (p = fill_opacities; p != NULL; p = p->next) {
148
+ if (p->fill_opacity == fill_opacity) return p->gs_num;
149
+ }
150
+ p = (Fill_Opacity_State *)calloc(1, sizeof(Fill_Opacity_State));
151
+ p->fill_opacity = fill_opacity;
152
+ p->gs_num = next_available_gs_number++;
153
+ p->obj_num = next_available_object_number++;
154
+ p->next = fill_opacities;
155
+ fill_opacities = p;
156
+ return p->gs_num;
157
+ }
158
+
159
+
160
+ void
161
+ c_fill_opacity_set(OBJ_PTR fmkr, FM *p, double fill_opacity, int *ierr)
162
+ { // /GSi gs for ExtGState obj with /cs set to fill opacity val
163
+ if (constructing_path) {
164
+ RAISE_ERROR("Sorry: must not be constructing a path when change fill "
165
+ "opacity", ierr);
166
+ return;
167
+ }
168
+ if (fill_opacity == p->fill_opacity) return;
169
+ int gs_num = Get_Fill_Opacity_XGS(fill_opacity);
170
+ fprintf(TF, "/GS%i gs\n", gs_num);
171
+ p->fill_opacity = fill_opacity;
172
+ }
173
+
174
+
175
+ void
176
+ Write_Stroke_Opacity_Objects(void)
177
+ {
178
+ Stroke_Opacity_State *p;
179
+ for (p = stroke_opacities; p != NULL; p = p->next) {
180
+ Record_Object_Offset(p->obj_num);
181
+ fprintf(OF, "%2i 0 obj << /Type /ExtGState /CA %g >> endobj\n",
182
+ p->obj_num, p->stroke_opacity);
183
+ }
184
+ }
185
+
186
+
187
+ void
188
+ Write_Fill_Opacity_Objects(void)
189
+ {
190
+ Fill_Opacity_State *p;
191
+ for (p = fill_opacities; p != NULL; p = p->next) {
192
+ Record_Object_Offset(p->obj_num);
193
+ fprintf(OF, "%2i 0 obj << /Type /ExtGState /ca %g >> endobj\n",
194
+ p->obj_num, p->fill_opacity);
195
+ }
196
+ }
197
+
198
+
199
+ /* Shading */
200
+
201
+ void
202
+ Free_Shadings()
203
+ {
204
+ Shading_Info *so;
205
+ while (shades_list != NULL) {
206
+ so = shades_list;
207
+ shades_list = so->next;
208
+ free(so);
209
+ }
210
+ }
211
+
212
+
213
+ void
214
+ Write_Shadings(void)
215
+ {
216
+ Shading_Info *so;
217
+ for (so = shades_list; so != NULL; so = so->next) {
218
+ Record_Object_Offset(so->obj_num);
219
+ fprintf(OF, "%i 0 obj <<\n", so->obj_num);
220
+ if (so->axial) {
221
+ fprintf(OF, "\t/ShadingType 2\n\t/Coords [%0.2f %0.2f %0.2f %0.2f]\n",
222
+ so->x0, so->y0, so->x1, so->y1);
223
+ }
224
+ else {
225
+ fprintf(OF, "\t/ShadingType 3\n\t/Coords "
226
+ "[%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f]\n",
227
+ so->x0, so->y0, so->r0, so->x1, so->y1, so->r1);
228
+ }
229
+ if (so->extend_start || so->extend_end)
230
+ fprintf(OF, "\t/Extend [ %s %s ]\n",
231
+ (so->extend_start)? "true" : "false",
232
+ (so->extend_end)? "true" : "false");
233
+ fprintf(OF, "\t/ColorSpace /DeviceRGB\n");
234
+ fprintf(OF, "\t/Function %i 0 R\n", so->function);
235
+ fprintf(OF, ">> endobj\n");
236
+ }
237
+ }
238
+
239
+
240
+ static void
241
+ c_axial_shading(FM *p, double x0, double y0, double x1, double y1,
242
+ int hival, int lookup_len, unsigned char *lookup,
243
+ bool extend_start, bool extend_end)
244
+ {
245
+ Shading_Info *so = (Shading_Info *)calloc(1, sizeof(Shading_Info));
246
+ so->next = shades_list;
247
+ shades_list = so;
248
+ so->shade_num = next_available_shade_number++;
249
+ so->obj_num = next_available_object_number++;
250
+ so->function = create_function(hival, lookup_len, lookup);
251
+ so->axial = true;
252
+ so->x0 = x0;
253
+ so->y0 = y0;
254
+ so->x1 = x1;
255
+ so->y1 = y1;
256
+ so->extend_start = extend_start;
257
+ so->extend_end = extend_end;
258
+ fprintf(TF, "/Shade%i sh\n", so->shade_num);
259
+ }
260
+
261
+
262
+ void
263
+ c_private_axial_shading(OBJ_PTR fmkr, FM *p, double x0, double y0, double x1,
264
+ double y1, OBJ_PTR colormap, bool extend_start,
265
+ bool extend_end, int *ierr)
266
+ {
267
+ int len = Array_Len(colormap, ierr);
268
+ if (*ierr != 0) return;
269
+ if (len != 2) {
270
+ RAISE_ERROR("Sorry: colormap must be array [hivalue, lookup]", ierr);
271
+ return;
272
+ }
273
+ OBJ_PTR hival = Array_Entry(colormap, 0, ierr);
274
+ OBJ_PTR lookup = Array_Entry(colormap, 1, ierr);
275
+ int hi_value = Number_to_int(hival, ierr);
276
+ int lookup_len = String_Len(lookup, ierr);
277
+ unsigned char *lookup_ptr = (unsigned char *)(String_Ptr(lookup, ierr));
278
+ if (*ierr != 0) return;
279
+ c_axial_shading(p, convert_figure_to_output_x(p, x0),
280
+ convert_figure_to_output_y(p, y0),
281
+ convert_figure_to_output_x(p, x1),
282
+ convert_figure_to_output_y(p, y1),
283
+ hi_value, lookup_len, lookup_ptr, extend_start, extend_end);
284
+ }
285
+
286
+
287
+ static void
288
+ c_radial_shading(FM *p, double x0, double y0, double r0, double x1, double y1,
289
+ double r1, int hival, int lookup_len, unsigned char *lookup,
290
+ double a, double b, double c, double d, double e, double f,
291
+ bool extend_start, bool extend_end)
292
+ {
293
+ Shading_Info *so = (Shading_Info *)calloc(1, sizeof(Shading_Info));
294
+ so->next = shades_list;
295
+ shades_list = so;
296
+ so->shade_num = next_available_shade_number++;
297
+ so->obj_num = next_available_object_number++;
298
+ so->function = create_function(hival, lookup_len, lookup);
299
+ so->axial = false;
300
+ so->x0 = x0;
301
+ so->y0 = y0;
302
+ so->r0 = r0;
303
+ so->x1 = x1;
304
+ so->y1 = y1;
305
+ so->r1 = r1;
306
+ so->extend_start = extend_start;
307
+ so->extend_end = extend_end;
308
+ if (a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0 || e != 0 || f != 0) {
309
+ fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /Shade%i sh Q\n",
310
+ a, b, c, d, e, f, so->shade_num);
311
+ }
312
+ else {
313
+ fprintf(TF, "/Shade%i sh\n", so->shade_num);
314
+ }
315
+ }
316
+
317
+
318
+ void
319
+ c_private_radial_shading(OBJ_PTR fmkr, FM *p,
320
+ double x0, double y0, double r0,
321
+ double x1, double y1, double r1, OBJ_PTR colormap,
322
+ double a, double b, double c, double d,
323
+ bool extend_start, bool extend_end, int *ierr)
324
+ {
325
+ int len = Array_Len(colormap, ierr);
326
+ if (*ierr != 0) return;
327
+ if (len != 2) {
328
+ RAISE_ERROR("Sorry: colormap must be array [hivalue, lookup]", ierr);
329
+ return;
330
+ }
331
+ OBJ_PTR hival = Array_Entry(colormap, 0, ierr);
332
+ OBJ_PTR lookup = Array_Entry(colormap, 1, ierr);
333
+ int hi_value = Number_to_int(hival, ierr);
334
+ int lookup_len = String_Len(lookup, ierr);
335
+ unsigned char *lookup_ptr = (unsigned char *)(String_Ptr(lookup, ierr));
336
+ if (*ierr != 0) return;
337
+ c_radial_shading(p, x0, y0, r0, x1, y1, r1,
338
+ hi_value, lookup_len, lookup_ptr,
339
+ convert_figure_to_output_dx(p, a),
340
+ convert_figure_to_output_dy(p, b),
341
+ convert_figure_to_output_dx(p, c),
342
+ convert_figure_to_output_dy(p, d),
343
+ convert_figure_to_output_x(p, 0.0),
344
+ convert_figure_to_output_y(p, 0.0),
345
+ extend_start, extend_end);
346
+ }
347
+
348
+
349
+ /* Colormaps */
350
+
351
+ static double
352
+ clr_value(double n1, double n2, double hue) // from plplot plctrl.c
353
+ {
354
+ double val;
355
+ while (hue >= 360.) hue -= 360.;
356
+ while (hue < 0.) hue += 360.;
357
+ if (hue < 60.) val = n1 + (n2 - n1) * hue / 60.;
358
+ else if (hue < 180.) val = n2;
359
+ else if (hue < 240.) val = n1 + (n2 - n1) * (240. - hue) / 60.;
360
+ else val = n1;
361
+ return val;
362
+ }
363
+
364
+
365
+ // this is also used for converting images
366
+ void
367
+ convert_hls_to_rgb(double h, double l, double s, double *p_r, double *p_g,
368
+ double *p_b) // from plplot plctrl.c
369
+ {
370
+ double m1, m2;
371
+ if (l <= .5) m2 = l * (s + 1.);
372
+ else m2 = l + s - l * s;
373
+ m1 = 2 * l - m2;
374
+ *p_r = clr_value(m1, m2, h + 120.);
375
+ *p_g = clr_value(m1, m2, h);
376
+ *p_b = clr_value(m1, m2, h - 120.);
377
+ }
378
+
379
+
380
+ static void
381
+ convert_rgb_to_hls(double r, double g, double b, double *p_h, double *p_l,
382
+ double *p_s) // from plplot plctrl.c
383
+ {
384
+ double h, l, s, d, rc, gc, bc, rgb_min, rgb_max;
385
+ rgb_min = MIN( r, MIN( g, b ));
386
+ rgb_max = MAX( r, MAX( g, b ));
387
+ l = (rgb_min + rgb_max) / 2.0;
388
+ if (rgb_min == rgb_max) s = h = 0;
389
+ else {
390
+ d = rgb_max - rgb_min;
391
+ if (l < 0.5) s = 0.5 * d / l;
392
+ else s = 0.5 * d / (1.-l);
393
+ rc = (rgb_max - r) / d;
394
+ gc = (rgb_max - g) / d;
395
+ bc = (rgb_max - b) / d;
396
+ if (r == rgb_max) h = bc - gc;
397
+ else if (g == rgb_max) h = rc - bc + 2;
398
+ else h = gc - rc - 2;
399
+ h = h * 60;
400
+ if (h < 0) h = h + 360;
401
+ else if (h >= 360) h = h - 360;
402
+ }
403
+ *p_h = h;
404
+ *p_l = l;
405
+ *p_s = s;
406
+ }
407
+
408
+
409
+ static double
410
+ linear_interpolate(int num_pts, double *xs, double *ys, double x)
411
+ {
412
+ int i;
413
+ if (num_pts == 1) return ys[0];
414
+ for (i = 0; i < num_pts; i++) {
415
+ if (xs[i] <= x && x < xs[i+1]) {
416
+ return ys[i] + (ys[i+1]-ys[i])*(x-xs[i])/(xs[i+1]-xs[i]);
417
+ }
418
+ }
419
+ return ys[num_pts-1];
420
+ }
421
+
422
+
423
+ static OBJ_PTR
424
+ c_create_colormap(FM *p, bool rgb_flag, int length, int num_pts, double *ps,
425
+ double *c1s, double *c2s, double *c3s, int *ierr)
426
+ {
427
+ int i;
428
+ if (ps[0] != 0.0 || ps[num_pts-1] != 1.0) {
429
+ RAISE_ERROR("Sorry: first control point for create colormap must be "
430
+ "at 0.0 and last must be at 1.0", ierr);
431
+ RETURN_NIL;
432
+ }
433
+ for (i = 1; i < num_pts; i++) {
434
+ if (ps[i-1] > ps[i]) {
435
+ RAISE_ERROR("Sorry: control points for create colormap must be "
436
+ "increasing from 0 to 1", ierr);
437
+ RETURN_NIL;
438
+ }
439
+ }
440
+ int j, buff_len = length * 3, hival = length - 1;
441
+ unsigned char *buff;
442
+ buff = ALLOC_N_unsigned_char(buff_len);
443
+ for (j = 0, i = 0; j < length; j++) {
444
+ double x = j; x /= (length-1);
445
+ double c1, c2, c3, r, g, b;
446
+ c1 = linear_interpolate(num_pts, ps, c1s, x);
447
+ c2 = linear_interpolate(num_pts, ps, c2s, x);
448
+ c3 = linear_interpolate(num_pts, ps, c3s, x);
449
+ if (rgb_flag) { r = c1; g = c2; b = c3; }
450
+ else convert_hls_to_rgb(c1, c2, c3, &r, &g, &b);
451
+ buff[i++] = ROUND(hival * r);
452
+ buff[i++] = ROUND(hival * g);
453
+ buff[i++] = ROUND(hival * b);
454
+ }
455
+ OBJ_PTR lookup = String_New((char *)buff, buff_len);
456
+ free(buff);
457
+ OBJ_PTR result = Array_New(2);
458
+ Array_Store(result, 0, Integer_New(hival), ierr);
459
+ Array_Store(result, 1, lookup, ierr);
460
+ if (*ierr != 0) RETURN_NIL;
461
+ return result;
462
+ }
463
+
464
+
465
+ /*
466
+ * create mappings from 'position' (0 to 1) to color (in HLS or RGB
467
+ * color spaces)
468
+ *
469
+ * the length parameter determines the number of entries in the color
470
+ * map (any integer between 2 and 256).
471
+ *
472
+ * for rgb, the colors are given as (red, green, blue) intensities
473
+ * from 0.0 to 1.0
474
+ *
475
+ * for hls, the colors are given as (hue, lightness, saturation)
476
+ * lightness and saturation given as values from 0.0 to 1.0 hue given
477
+ * as degrees (0 to 360) around the color wheel from
478
+ * red->green->blue->red
479
+ *
480
+ * Ps are the locations in (0 to 1) for the control points -- in
481
+ * increasing order
482
+ *
483
+ * must have Ps[0] == 0.0 and Ps[num_ps-1] == 1.0
484
+ */
485
+ OBJ_PTR
486
+ c_private_create_colormap(OBJ_PTR fmkr, FM *p, bool rgb, int length,
487
+ OBJ_PTR Ps, OBJ_PTR C1s, OBJ_PTR C2s, OBJ_PTR C3s,
488
+ int *ierr)
489
+ {
490
+ long p_len, c1_len, c2_len, c3_len;
491
+ double *p_ptr = Vector_Data_for_Read(Ps, &p_len, ierr);
492
+ if (*ierr != 0) RETURN_NIL;
493
+ double *c1_ptr = Vector_Data_for_Read(C1s, &c1_len, ierr);
494
+ if (*ierr != 0) RETURN_NIL;
495
+ double *c2_ptr = Vector_Data_for_Read(C2s, &c2_len, ierr);
496
+ if (*ierr != 0) RETURN_NIL;
497
+ double *c3_ptr = Vector_Data_for_Read(C3s, &c3_len, ierr);
498
+ if (*ierr != 0) RETURN_NIL;
499
+ if (p_len < 2 || p_len != c1_len || p_len != c2_len || p_len != c3_len) {
500
+ RAISE_ERROR("Sorry: vectors for create colormap must all be os same "
501
+ "length (with at least 2 entries)", ierr);
502
+ RETURN_NIL;
503
+ }
504
+ return c_create_colormap(p, rgb, length, p_len, p_ptr, c1_ptr, c2_ptr,
505
+ c3_ptr, ierr);
506
+ }
507
+
508
+
509
+ OBJ_PTR
510
+ c_get_color_from_colormap(OBJ_PTR fmkr, FM *p, OBJ_PTR color_map, double x,
511
+ int *ierr)
512
+ { // x is from 0 to 1. this returns a vector for the RGB color from
513
+ // the given colormap
514
+ OBJ_PTR cm_len_obj;
515
+ OBJ_PTR lookup_obj;
516
+ unsigned char *buff;
517
+ unsigned char r, g, b;
518
+ int i, cm_len, lu_len;
519
+
520
+ cm_len_obj = Array_Entry(color_map, 0, ierr);
521
+ if (*ierr != 0) RETURN_NIL;
522
+ cm_len = Number_to_int(cm_len_obj, ierr) + 1;
523
+ if (*ierr != 0) RETURN_NIL;
524
+ lookup_obj = Array_Entry(color_map, 1, ierr);
525
+ if (*ierr != 0) RETURN_NIL;
526
+ buff = (unsigned char *)(String_Ptr(lookup_obj,ierr));
527
+ if (*ierr != 0) RETURN_NIL;
528
+ lu_len = String_Len(lookup_obj,ierr);
529
+ if (*ierr != 0) RETURN_NIL;
530
+
531
+ if (3*cm_len != lu_len) {
532
+ RAISE_ERROR("Sorry: lookup length must be 3 times colormap length "
533
+ "(for R G B components)", ierr);
534
+ RETURN_NIL;
535
+ }
536
+ // Make sure x is non-negative
537
+ if (x < 0.0) x = -x;
538
+ i = 3 * (ROUND(x * (cm_len-1)) % cm_len);
539
+ r = buff[i]; g = buff[i+1]; b = buff[i+2];
540
+ OBJ_PTR result = Array_New(3);
541
+ Array_Store(result, 0, Float_New(r/255.0), ierr);
542
+ Array_Store(result, 1, Float_New(g/255.0), ierr);
543
+ Array_Store(result, 2, Float_New(b/255.0), ierr);
544
+ if (*ierr != 0) RETURN_NIL;
545
+ return result;
546
+ }
547
+
548
+
549
+ /*
550
+ * this creates an arbitrary mapping from positions to colors given as
551
+ * (r,g,b) triples
552
+ *
553
+ * the colormap size is set to the length of the vectors
554
+ *
555
+ * the Rs, Gs, and Bs are VALUEs from 0 to 1 representing the
556
+ * intensity of the color component
557
+ */
558
+ OBJ_PTR
559
+ c_convert_to_colormap(OBJ_PTR fmkr, FM* p, OBJ_PTR Rs, OBJ_PTR Gs, OBJ_PTR Bs,
560
+ int *ierr)
561
+ {
562
+
563
+ long r_len, g_len, b_len;
564
+ double *r_ptr = Vector_Data_for_Read(Rs, &r_len, ierr);
565
+ if (*ierr != 0) RETURN_NIL;
566
+ double *g_ptr = Vector_Data_for_Read(Gs, &g_len, ierr);
567
+ if (*ierr != 0) RETURN_NIL;
568
+ double *b_ptr = Vector_Data_for_Read(Bs, &b_len, ierr);
569
+ if (*ierr != 0) RETURN_NIL;
570
+ if (r_len <= 0 || r_len != g_len || b_len != g_len) {
571
+ RAISE_ERROR("Sorry: vectors for convert_to_colormap must all be of "
572
+ "same length", ierr);
573
+ RETURN_NIL;
574
+ }
575
+ int i, j, buff_len = r_len * 3;
576
+ unsigned char *buff;
577
+ buff = ALLOC_N_unsigned_char(buff_len);
578
+ for (i = 0, j = 0; j < r_len; j++) {
579
+ buff[i++] = ROUND(r_ptr[j]*255);
580
+ buff[i++] = ROUND(g_ptr[j]*255);
581
+ buff[i++] = ROUND(b_ptr[j]*255);
582
+ }
583
+ OBJ_PTR lookup = String_New((char *)buff, buff_len);
584
+ free(buff);
585
+ OBJ_PTR result = Array_New(2);
586
+ Array_Store(result, 0, Integer_New(r_len-1), ierr);
587
+ Array_Store(result, 1, lookup, ierr);
588
+ if (*ierr != 0) RETURN_NIL;
589
+ return result;
590
+ }
591
+
592
+
593
+ static void
594
+ Unpack_HLS(OBJ_PTR hls, double *hp, double *lp, double *sp, int *ierr)
595
+ {
596
+ int len = Array_Len(hls, ierr);
597
+ if (*ierr != 0) return;
598
+ if (len != 3) {
599
+ RAISE_ERROR("Sorry: invalid hls array: must have 3 entries", ierr);
600
+ return;
601
+ }
602
+ OBJ_PTR entry = Array_Entry(hls, 0, ierr); if (*ierr != 0) return;
603
+ double h = Number_to_double(entry, ierr); if (*ierr != 0) return;
604
+ entry = Array_Entry(hls, 1, ierr); if (*ierr != 0) return;
605
+ double l = Number_to_double(entry, ierr); if (*ierr != 0) return;
606
+ entry = Array_Entry(hls, 2, ierr); if (*ierr != 0) return;
607
+ double s = Number_to_double(entry, ierr); if (*ierr != 0) return;
608
+ if (l < 0.0 || l > 1.0) {
609
+ RAISE_ERROR_g("Sorry: invalid lightness (%g) for hls: must be between 0 "
610
+ "and 1", l, ierr);
611
+ return;
612
+ }
613
+ if (s < 0.0 || s > 1.0) {
614
+ RAISE_ERROR_g("Sorry: invalid saturation (%g) for hls: must be between "
615
+ "0 and 1", s, ierr);
616
+ return;
617
+ }
618
+ *hp = h; *lp = l; *sp = s;
619
+ }
620
+
621
+
622
+ OBJ_PTR
623
+ c_hls_to_rgb(OBJ_PTR fmkr, FM *p, OBJ_PTR hls_vec, int *ierr)
624
+ {
625
+ double h = 0.0, l = 0.0, s = 0.0, r = 0.0, g = 0.0, b = 0.0;
626
+ Unpack_HLS(hls_vec, &h, &l, &s, ierr);
627
+ if (*ierr != 0) RETURN_NIL;
628
+ convert_hls_to_rgb(h, l, s, &r, &g, &b);
629
+ OBJ_PTR result = Array_New(3);
630
+ Array_Store(result, 0, Float_New(r), ierr);
631
+ Array_Store(result, 1, Float_New(g), ierr);
632
+ Array_Store(result, 2, Float_New(b), ierr);
633
+ return result;
634
+ }
635
+
636
+
637
+
638
+ OBJ_PTR
639
+ c_rgb_to_hls(OBJ_PTR fmkr, FM *p, OBJ_PTR rgb_vec, int *ierr)
640
+ {
641
+ /*
642
+ * hue is given as an angle from 0 to 360 around the color wheel.
643
+ *
644
+ * 0, 60, 120, 180, 240, and 300 are respectively red, yellow,
645
+ * green, cyan, blue, and magenta.
646
+ *
647
+ * lightness and saturation are given as numbers from 0 to 1
648
+ */
649
+ double h, l, s, r, g, b;
650
+ Unpack_RGB(rgb_vec, &r, &g, &b, ierr);
651
+ if (*ierr != 0) RETURN_NIL;
652
+ convert_rgb_to_hls(r, g, b, &h, &l, &s);
653
+ OBJ_PTR result = Array_New(3);
654
+ Array_Store(result, 0, Float_New(h), ierr);
655
+ Array_Store(result, 1, Float_New(l), ierr);
656
+ Array_Store(result, 2, Float_New(s), ierr);
657
+ return result;
658
+ }
659
+
660
+
661
+ void
662
+ c_title_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
663
+ {
664
+ double r, g, b;
665
+ Unpack_RGB(val, &r, &g, &b, ierr);
666
+ if (*ierr != 0) return;
667
+ p->title_color_R = r;
668
+ p->title_color_G = g;
669
+ p->title_color_B = b;
670
+ }
671
+
672
+
673
+ OBJ_PTR
674
+ c_title_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
675
+ {
676
+ // value is array of [r, g, b] intensities from 0 to 1
677
+ // r g b RG
678
+ double r, g, b;
679
+ r = p->title_color_R;
680
+ g = p->title_color_G;
681
+ b = p->title_color_B;
682
+ OBJ_PTR result = Array_New(3);
683
+ Array_Store(result, 0, Float_New(r), ierr);
684
+ Array_Store(result, 1, Float_New(g), ierr);
685
+ Array_Store(result, 2, Float_New(b), ierr);
686
+ return result;
687
+ }
688
+
689
+
690
+ void
691
+ c_xlabel_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
692
+ {
693
+ double r, g, b;
694
+ Unpack_RGB(val, &r, &g, &b, ierr);
695
+ if (*ierr != 0) return;
696
+ p->xlabel_color_R = r;
697
+ p->xlabel_color_G = g;
698
+ p->xlabel_color_B = b;
699
+ }
700
+
701
+
702
+ OBJ_PTR
703
+ c_xlabel_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
704
+ {
705
+ // value is array of [r, g, b] intensities from 0 to 1
706
+ // r g b RG
707
+ double r, g, b;
708
+ r = p->xlabel_color_R;
709
+ g = p->xlabel_color_G;
710
+ b = p->xlabel_color_B;
711
+ OBJ_PTR result = Array_New(3);
712
+ Array_Store(result, 0, Float_New(r), ierr);
713
+ Array_Store(result, 1, Float_New(g), ierr);
714
+ Array_Store(result, 2, Float_New(b), ierr);
715
+ return result;
716
+ }
717
+
718
+
719
+ void
720
+ c_ylabel_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
721
+ {
722
+ double r, g, b;
723
+ Unpack_RGB(val, &r, &g, &b, ierr);
724
+ if (*ierr != 0) return;
725
+ p->ylabel_color_R = r;
726
+ p->ylabel_color_G = g;
727
+ p->ylabel_color_B = b;
728
+ }
729
+
730
+
731
+ OBJ_PTR
732
+ c_ylabel_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
733
+ {
734
+ // value is array of [r, g, b] intensities from 0 to 1
735
+ // r g b RG
736
+ double r, g, b;
737
+ r = p->ylabel_color_R;
738
+ g = p->ylabel_color_G;
739
+ b = p->ylabel_color_B;
740
+ OBJ_PTR result = Array_New(3);
741
+ Array_Store(result, 0, Float_New(r), ierr);
742
+ Array_Store(result, 1, Float_New(g), ierr);
743
+ Array_Store(result, 2, Float_New(b), ierr);
744
+ return result;
745
+ }
746
+
747
+
748
+ void
749
+ c_xaxis_stroke_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
750
+ {
751
+ double r, g, b;
752
+ Unpack_RGB(val, &r, &g, &b, ierr);
753
+ if (*ierr != 0) return;
754
+ p->xaxis_stroke_color_R = r;
755
+ p->xaxis_stroke_color_G = g;
756
+ p->xaxis_stroke_color_B = b;
757
+ }
758
+
759
+
760
+
761
+ OBJ_PTR
762
+ c_xaxis_stroke_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
763
+ {
764
+ // value is array of [r, g, b] intensities from 0 to 1
765
+ // r g b RG
766
+ double r, g, b;
767
+ r = p->xaxis_stroke_color_R;
768
+ g = p->xaxis_stroke_color_G;
769
+ b = p->xaxis_stroke_color_B;
770
+ OBJ_PTR result = Array_New(3);
771
+ Array_Store(result, 0, Float_New(r), ierr);
772
+ Array_Store(result, 1, Float_New(g), ierr);
773
+ Array_Store(result, 2, Float_New(b), ierr);
774
+ return result;
775
+ }
776
+
777
+
778
+ void
779
+ c_yaxis_stroke_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
780
+ {
781
+ double r, g, b;
782
+ Unpack_RGB(val, &r, &g, &b, ierr);
783
+ if (*ierr != 0) return;
784
+ p->yaxis_stroke_color_R = r;
785
+ p->yaxis_stroke_color_G = g;
786
+ p->yaxis_stroke_color_B = b;
787
+ }
788
+
789
+
790
+ OBJ_PTR
791
+ c_yaxis_stroke_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
792
+ {
793
+ // value is array of [r, g, b] intensities from 0 to 1
794
+ // r g b RG
795
+ double r, g, b;
796
+ r = p->yaxis_stroke_color_R;
797
+ g = p->yaxis_stroke_color_G;
798
+ b = p->yaxis_stroke_color_B;
799
+ OBJ_PTR result = Array_New(3);
800
+ Array_Store(result, 0, Float_New(r), ierr);
801
+ Array_Store(result, 1, Float_New(g), ierr);
802
+ Array_Store(result, 2, Float_New(b), ierr);
803
+ return result;
804
+ }
805
+
806
+ /* Accessors for tick label colors */
807
+
808
+ void
809
+ c_xaxis_labels_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
810
+ {
811
+ double r, g, b;
812
+ Unpack_RGB(val, &r, &g, &b, ierr);
813
+ if (*ierr != 0) return;
814
+ p->xaxis_labels_color_R = r;
815
+ p->xaxis_labels_color_G = g;
816
+ p->xaxis_labels_color_B = b;
817
+ }
818
+
819
+
820
+
821
+ OBJ_PTR
822
+ c_xaxis_labels_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
823
+ {
824
+ // value is array of [r, g, b] intensities from 0 to 1
825
+ // r g b RG
826
+ double r, g, b;
827
+ r = p->xaxis_labels_color_R;
828
+ g = p->xaxis_labels_color_G;
829
+ b = p->xaxis_labels_color_B;
830
+ OBJ_PTR result = Array_New(3);
831
+ Array_Store(result, 0, Float_New(r), ierr);
832
+ Array_Store(result, 1, Float_New(g), ierr);
833
+ Array_Store(result, 2, Float_New(b), ierr);
834
+ return result;
835
+ }
836
+
837
+
838
+ void
839
+ c_yaxis_labels_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
840
+ {
841
+ double r, g, b;
842
+ Unpack_RGB(val, &r, &g, &b, ierr);
843
+ if (*ierr != 0) return;
844
+ p->yaxis_labels_color_R = r;
845
+ p->yaxis_labels_color_G = g;
846
+ p->yaxis_labels_color_B = b;
847
+ }
848
+
849
+
850
+ OBJ_PTR
851
+ c_yaxis_labels_color_get(OBJ_PTR fmkr, FM *p, int *ierr)
852
+ {
853
+ // value is array of [r, g, b] intensities from 0 to 1
854
+ // r g b RG
855
+ double r, g, b;
856
+ r = p->yaxis_labels_color_R;
857
+ g = p->yaxis_labels_color_G;
858
+ b = p->yaxis_labels_color_B;
859
+ OBJ_PTR result = Array_New(3);
860
+ Array_Store(result, 0, Float_New(r), ierr);
861
+ Array_Store(result, 1, Float_New(g), ierr);
862
+ Array_Store(result, 2, Float_New(b), ierr);
863
+ return result;
864
+ }
865
+
866
+
867
+
868
+ void
869
+ str_hls_to_rgb_bang(unsigned char* str, long len)
870
+ {
871
+ double r,g,b,h,l,s;
872
+ long n, j;
873
+ // convert HLS triples to RGB triples
874
+ n = len/3;
875
+ for (j=0; j<n; j++) {
876
+ // 360/256 = 1.40625
877
+ h = str[0]*1.40625; l = str[1]/255.0; s = str[2]/255.0;
878
+ convert_hls_to_rgb(h,l,s,&r,&g,&b);
879
+ *str++ = round(r*255.0); *str++ = round(g*255.0); *str++ = round(b*255.0);
880
+ }
881
+ }
882
+
883
+
884
+ void
885
+ c_string_hls_to_rgb_bang(OBJ_PTR fmkr, FM *p, unsigned char* str, long len, int *ierr)
886
+ { str_hls_to_rgb_bang(str,len); }
887
+
888
+ void
889
+ c_string_rgb_to_hls_bang(OBJ_PTR fmkr, FM *p, unsigned char* str, long len, int *ierr)
890
+ {
891
+ double r,g,b,h,l,s;
892
+ long n, j;
893
+ // convert RGB triples to HLS triples
894
+ n = len/3;
895
+ for (j=0; j<n; j++) {
896
+ // 360/256 = 1.40625
897
+ r = str[0]/255.0; g = str[1]/255.0; b = str[2]/255.0;
898
+ convert_rgb_to_hls(r, g, b, &h, &l, &s);
899
+ *str++ = round(h/1.40625); *str++ = round(l*255.0); *str++ = round(s*255.0);
900
+ }
901
+ }
902
+
903
+
904
+