tioga 1.17 → 1.18
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.
- data/Tioga_README +14 -3
- data/ext/Dobjects/Dvector/dvector.c +123 -28
- data/ext/Tioga/FigureMaker/__shared_axes.c +6 -2
- data/ext/Tioga/FigureMaker/__shared_pdfimage.c +256 -66
- data/ext/Tioga/FigureMaker/figures.c +12 -7
- data/ext/Tioga/FigureMaker/figures.h +18 -1
- data/ext/Tioga/FigureMaker/pdfs.h +8 -0
- data/ext/Tioga/FigureMaker/shared/axes.c +6 -2
- data/ext/Tioga/FigureMaker/shared/pdfimage.c +256 -66
- data/ext/Tioga/FigureMaker/wrappers.c +67 -41
- data/ext/Tioga/FigureMaker/wrappers.h +22 -18
- data/lib/Dobjects/Dvector_extras.rb +2 -0
- data/lib/Tioga/FigMkr.rb +175 -68
- data/lib/Tioga/Images.rb +64 -4
- data/tests/tc_Dvector.rb +45 -0
- metadata +2 -2
data/Tioga_README
CHANGED
@@ -22,9 +22,16 @@ This is the README for the Tioga kernel, version 1.14, June 10, 2011.
|
|
22
22
|
|
23
23
|
<< What's new >>
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
Tioga 1.18 brings in a few new features. First, Dvector.fancy_read
|
26
|
+
is now able to extract pure text columns. Second, a jpg_info function
|
27
|
+
has been added that read the width and height from within a JPEG file,
|
28
|
+
for use with show_image: you now don't have to know the image size
|
29
|
+
beforehand. A load_png function was added that relies on pdflatex to
|
30
|
+
read PNG files (except those with a custom palette). Feed the return
|
31
|
+
value of load_png to show_image. It is now possible to reuse an image
|
32
|
+
over and over again by saving its reference and using itagain.Finally,
|
33
|
+
more control over the number of pdflatex executions is now available.
|
34
|
+
There are also a couple of bug fixes.
|
28
35
|
|
29
36
|
<< Quick Installation of Tioga >>
|
30
37
|
|
@@ -164,6 +171,10 @@ Bill Paxton
|
|
164
171
|
|
165
172
|
Here are the old release messages:
|
166
173
|
|
174
|
+
Tioga 1.17 provides all the necessary fixes to have it run on
|
175
|
+
windows, so now we also support the Redmond operating system (works
|
176
|
+
with the ProTeXt LaTeX distribution).
|
177
|
+
|
167
178
|
Tioga 1.16 brings in a bug fix by Josiah Schwab in handling some
|
168
179
|
HLS triplets. It also provides facilities to extract the pdflatex
|
169
180
|
errors.
|
@@ -5623,6 +5623,12 @@ static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
|
|
5623
5623
|
return retval;
|
5624
5624
|
}
|
5625
5625
|
|
5626
|
+
static VALUE marked_array()
|
5627
|
+
{
|
5628
|
+
VALUE v = rb_ary_new();
|
5629
|
+
rb_gc_register_mark_object(v);
|
5630
|
+
return v;
|
5631
|
+
}
|
5626
5632
|
|
5627
5633
|
/*
|
5628
5634
|
:call-seq:
|
@@ -5637,12 +5643,16 @@ static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
|
|
5637
5643
|
* 'skip_first': skips that many lines before reading anything
|
5638
5644
|
* 'index_col': if true, the first column returned contains the
|
5639
5645
|
number of the line read
|
5640
|
-
* 'remove_space': whether to remove spaces at the beginning of a line.
|
5641
|
-
option is currently not implemented !*
|
5646
|
+
* 'remove_space': whether to remove spaces at the beginning of a line.
|
5642
5647
|
* 'comment_out': this should be an array into which the comments
|
5643
5648
|
will be dumped one by one.
|
5644
5649
|
* 'default': what to put when nothing was found but a number must be used
|
5645
|
-
|
5650
|
+
* 'last_col': when this is specified, it represents the last column which
|
5651
|
+
is read and parsed as numbers (0-based, so the 3rd column is 2).
|
5652
|
+
The remaining is returned as text in one n+1 column
|
5653
|
+
* 'text_columns': if provided, it is an array of integers containing the
|
5654
|
+
0-based indices of columns to be parsed as text rather than numbers.
|
5655
|
+
|
5646
5656
|
In addition to these options that control the output, here are a few
|
5647
5657
|
others to tune memory allocation; these can strongly improve the
|
5648
5658
|
performance (or make it worse if you wish):
|
@@ -5666,11 +5676,65 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
5666
5676
|
VALUE comments = rb_hash_aref(options, rb_str_new2("comments"));
|
5667
5677
|
VALUE comment_out = rb_hash_aref(options, rb_str_new2("comment_out"));
|
5668
5678
|
|
5679
|
+
/* Elements after that many columns */
|
5680
|
+
VALUE lc = rb_hash_aref(options, rb_str_new2("last_col"));
|
5681
|
+
long last_col = RTEST(lc) ? FIX2LONG(lc) : -1;
|
5682
|
+
VALUE text_columns = rb_hash_aref(options, rb_str_new2("text_columns"));
|
5683
|
+
|
5669
5684
|
/* Then, some various variables: */
|
5670
5685
|
VALUE line;
|
5671
5686
|
|
5672
5687
|
ID chomp_id = rb_intern("chomp!");
|
5673
5688
|
ID gets_id = rb_intern("gets");
|
5689
|
+
ID max_id = rb_intern("max");
|
5690
|
+
ID size_id = rb_intern("size");
|
5691
|
+
|
5692
|
+
/* We compute the maximum number of text columns */
|
5693
|
+
long last_text_col = last_col+1;
|
5694
|
+
VALUE mx = RTEST(text_columns) ? rb_funcall(text_columns, max_id, 0) : Qnil;
|
5695
|
+
if(RTEST(mx) && last_text_col < 0) { /* Only taking the max into
|
5696
|
+
account if the last col
|
5697
|
+
stuff is not on */
|
5698
|
+
long d = FIX2LONG(mx);
|
5699
|
+
last_text_col = d;
|
5700
|
+
}
|
5701
|
+
|
5702
|
+
|
5703
|
+
/* array of Ruby arrays containing the text objects of interest */
|
5704
|
+
VALUE * text_cols = NULL;
|
5705
|
+
|
5706
|
+
/*
|
5707
|
+
Handling of text columns.
|
5708
|
+
|
5709
|
+
The number and position of text columns has to be known in
|
5710
|
+
advance. For each of those, the value of text_columns isn't Qnil,
|
5711
|
+
and the corresponding column is NULL.
|
5712
|
+
|
5713
|
+
*/
|
5714
|
+
if(last_text_col >= 0) {
|
5715
|
+
text_cols = ALLOC_N(VALUE, last_text_col + 1);
|
5716
|
+
int i;
|
5717
|
+
for(i = 0; i < last_text_col + 1; i++)
|
5718
|
+
text_cols[i] = Qnil;
|
5719
|
+
if(last_col >= 0) {
|
5720
|
+
text_cols[last_col+1] = marked_array();
|
5721
|
+
}
|
5722
|
+
if(RTEST(mx)) {
|
5723
|
+
/* Todo */
|
5724
|
+
int sz = RARRAY_LENINT(text_columns);
|
5725
|
+
int i;
|
5726
|
+
for(i = 0; i < sz; i++) {
|
5727
|
+
long idx = FIX2LONG(rb_ary_entry(text_columns, i));
|
5728
|
+
if(idx >= 0 && (last_col < 0 || idx < last_col)) {
|
5729
|
+
text_cols[idx] = marked_array();
|
5730
|
+
}
|
5731
|
+
}
|
5732
|
+
}
|
5733
|
+
}
|
5734
|
+
|
5735
|
+
|
5736
|
+
|
5737
|
+
|
5674
5738
|
long line_number = 0;
|
5675
5739
|
|
5676
5740
|
/*
|
@@ -5690,6 +5754,8 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
5690
5754
|
|
5691
5755
|
|
5692
5756
|
int i;
|
5757
|
+
for(i = 0; i < current_size; i++)
|
5758
|
+
vectors[i] = NULL;
|
5693
5759
|
|
5694
5760
|
/* The return value */
|
5695
5761
|
VALUE ary;
|
@@ -5742,47 +5808,76 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
5742
5808
|
pre = post;
|
5743
5809
|
post = Qnil;
|
5744
5810
|
}
|
5745
|
-
|
5746
|
-
|
5747
|
-
|
5748
|
-
|
5749
|
-
|
5750
|
-
|
5751
|
-
|
5752
|
-
|
5753
|
-
|
5754
|
-
|
5755
|
-
|
5756
|
-
|
5757
|
-
|
5758
|
-
|
5759
|
-
|
5760
|
-
|
5761
|
-
|
5811
|
+
if(text_cols && col <= last_text_col && RTEST(text_cols[col])) {
|
5812
|
+
rb_ary_push(text_cols[col], pre);
|
5813
|
+
if(col >= nb_vectors) {
|
5814
|
+
nb_vectors ++;
|
5815
|
+
if(col < current_size)
|
5816
|
+
vectors[col] = NULL;
|
5817
|
+
}
|
5818
|
+
}
|
5819
|
+
else {
|
5820
|
+
a = StringValueCStr(pre);
|
5821
|
+
double c = strtod(a, &b);
|
5822
|
+
if(b == a)
|
5823
|
+
c = def;
|
5824
|
+
if(col >= nb_vectors) {
|
5825
|
+
/* We need to create a new vector */
|
5826
|
+
if(col >= current_size) { /* Increase the available size */
|
5827
|
+
current_size = col + 5;
|
5828
|
+
REALLOC_N(vectors, double * , current_size);
|
5829
|
+
}
|
5830
|
+
for(; nb_vectors <= col; nb_vectors++)
|
5831
|
+
vectors[nb_vectors] = NULL; /* default to NULL */
|
5832
|
+
|
5833
|
+
double * vals = vectors[col] = ALLOC_N(double, allocated_size);
|
5834
|
+
/* Filling it with the default value */
|
5835
|
+
for(i = 0; i < index; i++) {
|
5836
|
+
vals[i] = def;
|
5837
|
+
}
|
5838
|
+
}
|
5839
|
+
vectors[col][index] = c;
|
5762
5840
|
}
|
5763
|
-
vectors[col][index] = c;
|
5764
5841
|
col++;
|
5842
|
+
if(last_col >= 0 && col > last_col) {
|
5843
|
+
rb_ary_push(text_cols[last_col + 1], post);
|
5844
|
+
nb_vectors = col + 1;
|
5845
|
+
col++;
|
5846
|
+
break;
|
5847
|
+
}
|
5765
5848
|
}
|
5766
5849
|
/* Now, we finish the line */
|
5767
|
-
for(; col < nb_vectors; col++)
|
5768
|
-
|
5850
|
+
for(; col < nb_vectors; col++) {
|
5851
|
+
if(text_cols && col <= last_text_col && RTEST(text_cols[col]))
|
5852
|
+
rb_ary_push(text_cols[col], Qnil);
|
5853
|
+
else
|
5854
|
+
vectors[col][index] = def;
|
5855
|
+
}
|
5769
5856
|
index++;
|
5770
5857
|
/* Now, we reallocate memory if necessary */
|
5771
5858
|
if(index >= allocated_size) {
|
5772
5859
|
allocated_size *= 2; /* We double the size */
|
5773
|
-
for(col = 0; col < nb_vectors; col++)
|
5774
|
-
|
5860
|
+
for(col = 0; col < nb_vectors; col++) {
|
5861
|
+
if(col < current_size && vectors[col])
|
5862
|
+
REALLOC_N(vectors[col], double, allocated_size);
|
5863
|
+
}
|
5775
5864
|
}
|
5776
5865
|
}
|
5777
5866
|
/* Now, we make up the array */
|
5778
5867
|
ary = rb_ary_new();
|
5779
5868
|
for(i = 0; i < nb_vectors; i++) {
|
5780
5869
|
/* We create a vector */
|
5781
|
-
|
5782
|
-
|
5783
|
-
|
5870
|
+
if(text_cols && i <= last_text_col && RTEST(text_cols[i]))
|
5871
|
+
rb_ary_store(ary, i, text_cols[i]);
|
5872
|
+
else {
|
5873
|
+
rb_ary_store(ary, i, make_dvector_from_data(cDvector, index, vectors[i]));
|
5874
|
+
/* And free the memory */
|
5875
|
+
free(vectors[i]);
|
5876
|
+
}
|
5784
5877
|
}
|
5785
5878
|
free(vectors);
|
5879
|
+
if(text_cols)
|
5880
|
+
free(text_cols);
|
5786
5881
|
return ary;
|
5787
5882
|
}
|
5788
5883
|
|
@@ -340,8 +340,12 @@ static char *Create_Label(double val, int scale, int prec,
|
|
340
340
|
/* Exponential, i.e. 10^-1, 1, 10, 10^2, etc */
|
341
341
|
double abs_diff = fabs(val - exponent);
|
342
342
|
if (abs_diff > 0.1) snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{10^{%0.1f}}" : "\\tiogaxaxisnumericlabel{10^{%0.1f}}", val);
|
343
|
-
else if (exponent == 0) strcpy(buff,
|
344
|
-
|
343
|
+
else if (exponent == 0) strcpy(buff, (s->vertical)?
|
344
|
+
"\\tiogayaxisnumericlabel{1}" :
|
345
|
+
"\\tiogaxaxisnumericlabel{1}");
|
346
|
+
else if (exponent == 1) strcpy(buff, (s->vertical)?
|
347
|
+
"\\tiogayaxisnumericlabel{10}" :
|
348
|
+
"\\tiogaxaxisnumericlabel{10}");
|
345
349
|
else snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{10^{%d}}" : "\\tiogaxaxisnumericlabel{10^{%d}}", exponent);
|
346
350
|
} else { /* Linear */
|
347
351
|
double scale2;
|
@@ -74,7 +74,122 @@
|
|
74
74
|
/Decode [1 0] means sample values of 1 are included in the output, values of 0 are excluded
|
75
75
|
|
76
76
|
*/
|
77
|
-
|
77
|
+
|
78
|
+
/*
|
79
|
+
Reads next byte, and set *eof on end of file
|
80
|
+
*/
|
81
|
+
static int read_byte(FILE * file, int *eof)
|
82
|
+
{
|
83
|
+
int c = fgetc(file);
|
84
|
+
if(c == EOF)
|
85
|
+
*eof = 1;
|
86
|
+
else
|
87
|
+
*eof = 0;
|
88
|
+
return c;
|
89
|
+
}
|
90
|
+
|
91
|
+
/* Reads a 16 bits word */
|
92
|
+
static unsigned read_word(FILE * file, int *eof)
|
93
|
+
{
|
94
|
+
int v = fgetc(file);
|
95
|
+
int c = fgetc(file);
|
96
|
+
if(v == EOF || c == EOF)
|
97
|
+
*eof = 1;
|
98
|
+
else
|
99
|
+
*eof = 0;
|
100
|
+
return ((unsigned) v) << 8 | ((unsigned) c);
|
101
|
+
}
|
102
|
+
|
103
|
+
/* Reads until the next tag, and returns its code */
|
104
|
+
static int read_next_tag(FILE * file, int *eof)
|
105
|
+
{
|
106
|
+
int c;
|
107
|
+
*eof = 0;
|
108
|
+
|
109
|
+
/* Discard non 0xFF bytes */
|
110
|
+
do {
|
111
|
+
c = read_byte(file, eof);
|
112
|
+
if(*eof)
|
113
|
+
return 0xFF;
|
114
|
+
} while(c != 0xFF);
|
115
|
+
|
116
|
+
do {
|
117
|
+
c = read_byte(file, eof);
|
118
|
+
if(*eof)
|
119
|
+
return 0xFF;
|
120
|
+
} while (c == 0xFF);
|
121
|
+
return c;
|
122
|
+
}
|
123
|
+
|
124
|
+
static void skip_variable_length(FILE * file, int *eof)
|
125
|
+
{
|
126
|
+
*eof = 0;
|
127
|
+
int len = read_word(file, eof);
|
128
|
+
if(*eof)
|
129
|
+
return;
|
130
|
+
if(len < 2) {
|
131
|
+
*eof = 1;
|
132
|
+
return;
|
133
|
+
}
|
134
|
+
len -= 2;
|
135
|
+
while(len > 0) {
|
136
|
+
--len;
|
137
|
+
read_byte(file, eof);
|
138
|
+
if(*eof)
|
139
|
+
return;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
/* Parses a JPEG file and extracts the resolution data from it, and
|
145
|
+
returns a newly allocated JPG_Info structure.
|
146
|
+
*/
|
147
|
+
JPG_Info * Parse_JPG(const char * file)
|
148
|
+
{
|
149
|
+
|
150
|
+
FILE * f = fopen(file, "rb");
|
151
|
+
if(! f)
|
152
|
+
return NULL;
|
153
|
+
|
154
|
+
int eof = 0;
|
155
|
+
int tag = read_next_tag(f, &eof);
|
156
|
+
if(tag != 0xD8 || eof) {
|
157
|
+
fclose(f);
|
158
|
+
return NULL;
|
159
|
+
}
|
160
|
+
|
161
|
+
while(1) {
|
162
|
+
tag = read_next_tag(f, &eof);
|
163
|
+
if(eof) {
|
164
|
+
fclose(f);
|
165
|
+
return NULL;
|
166
|
+
}
|
167
|
+
switch(tag) {
|
168
|
+
case 0xC0: /* image data */
|
169
|
+
{
|
170
|
+
int len = read_word(f, &eof);
|
171
|
+
int bps = read_byte(f, &eof);
|
172
|
+
int y = read_word(f, &eof);
|
173
|
+
int x = read_word(f, &eof);
|
174
|
+
int cmps = read_byte(f, &eof);
|
175
|
+
fclose(f);
|
176
|
+
if(eof)
|
177
|
+
return NULL;
|
178
|
+
|
179
|
+
JPG_Info * val = (JPG_Info *)calloc(1, sizeof(JPG_Info));
|
180
|
+
val->filename = ALLOC_N_char(strlen(file)+1);
|
181
|
+
strcpy(val->filename, file);
|
182
|
+
val->width = x;
|
183
|
+
val->height = y;
|
184
|
+
return val;
|
185
|
+
}
|
186
|
+
default:
|
187
|
+
skip_variable_length(f, &eof);
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
|
78
193
|
|
79
194
|
void
|
80
195
|
Free_JPG(JPG_Info *xo)
|
@@ -88,6 +203,7 @@ Free_Sampled(Sampled_Info *xo)
|
|
88
203
|
{
|
89
204
|
if (xo->image_data != NULL) free(xo->image_data);
|
90
205
|
if (xo->lookup != NULL) free(xo->lookup);
|
206
|
+
if (xo->filters != NULL) free(xo->filters);
|
91
207
|
}
|
92
208
|
|
93
209
|
|
@@ -164,7 +280,7 @@ void
|
|
164
280
|
Write_Sampled(Sampled_Info *xo, int *ierr)
|
165
281
|
{
|
166
282
|
fprintf(OF, "\n\t/Subtype /Image\n");
|
167
|
-
fprintf(OF, "\t/
|
283
|
+
fprintf(OF, "\t/Interpolate %s\n",
|
168
284
|
(xo->interpolate)? "true":"false");
|
169
285
|
fprintf(OF, "\t/Height %i\n", xo->height);
|
170
286
|
fprintf(OF, "\t/Width %i\n", xo->width);
|
@@ -172,19 +288,20 @@ Write_Sampled(Sampled_Info *xo, int *ierr)
|
|
172
288
|
unsigned long new_len;
|
173
289
|
unsigned char *image_data;
|
174
290
|
unsigned char *buffer;
|
291
|
+
unsigned char *wd;
|
175
292
|
switch (xo->image_type) {
|
176
293
|
case RGB_IMAGE:
|
177
294
|
case HLS_IMAGE:
|
178
295
|
fprintf(OF, "\t/ColorSpace /DeviceRGB\n");
|
179
|
-
fprintf(OF, "\t/BitsPerComponent
|
296
|
+
fprintf(OF, "\t/BitsPerComponent %d\n", xo->components);
|
180
297
|
break;
|
181
298
|
case CMYK_IMAGE:
|
182
299
|
fprintf(OF, "\t/ColorSpace /DeviceCMYK\n");
|
183
|
-
fprintf(OF, "\t/BitsPerComponent
|
300
|
+
fprintf(OF, "\t/BitsPerComponent %d\n", xo->components);
|
184
301
|
break;
|
185
302
|
case GRAY_IMAGE:
|
186
303
|
fprintf(OF, "\t/ColorSpace /DeviceGray\n");
|
187
|
-
fprintf(OF, "\t/BitsPerComponent
|
304
|
+
fprintf(OF, "\t/BitsPerComponent %d\n", xo->components);
|
188
305
|
break;
|
189
306
|
case MONO_IMAGE:
|
190
307
|
fprintf(OF, "\t/ImageMask true\n");
|
@@ -202,7 +319,7 @@ Write_Sampled(Sampled_Info *xo, int *ierr)
|
|
202
319
|
else fprintf(OF, "%x", c);
|
203
320
|
}
|
204
321
|
fprintf(OF, "> ]\n");
|
205
|
-
fprintf(OF, "\t/BitsPerComponent
|
322
|
+
fprintf(OF, "\t/BitsPerComponent %d\n", xo->components);
|
206
323
|
}
|
207
324
|
if (xo->mask_obj_num > 0) {
|
208
325
|
if (xo->image_type == MONO_IMAGE) {
|
@@ -226,22 +343,35 @@ Write_Sampled(Sampled_Info *xo, int *ierr)
|
|
226
343
|
} else {
|
227
344
|
image_data = xo->image_data;
|
228
345
|
}
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
346
|
+
|
347
|
+
buffer = NULL;
|
348
|
+
wd = image_data;
|
349
|
+
|
350
|
+
if(xo->filters) {
|
351
|
+
new_len = xo->length;
|
352
|
+
fprintf(OF, "%s", xo->filters);
|
353
|
+
}
|
354
|
+
else {
|
355
|
+
fprintf(OF, "\t/Filter /FlateDecode\n");
|
356
|
+
|
357
|
+
new_len = (xo->length * 11)/10 + 100;
|
358
|
+
buffer = ALLOC_N_unsigned_char(new_len);
|
359
|
+
if (do_flate_compress(buffer, &new_len, image_data, xo->length)
|
360
|
+
!= FLATE_OK) {
|
361
|
+
free(buffer);
|
362
|
+
RAISE_ERROR("Error compressing image data", ierr);
|
363
|
+
return;
|
364
|
+
}
|
365
|
+
wd = buffer;
|
237
366
|
}
|
238
367
|
fprintf(OF, "\t/Length %li\n", new_len);
|
239
368
|
fprintf(OF, "\t>>\nstream\n");
|
240
|
-
if (fwrite(
|
369
|
+
if (fwrite(wd, 1, new_len, OF) < new_len) {
|
241
370
|
RAISE_ERROR("Error writing image data", ierr);
|
242
371
|
return;
|
243
372
|
}
|
244
|
-
|
373
|
+
if(buffer)
|
374
|
+
free(buffer);
|
245
375
|
if (xo->image_type == HLS_IMAGE) free(image_data);
|
246
376
|
fprintf(OF, "\nendstream\nendobj\n");
|
247
377
|
}
|
@@ -258,8 +388,29 @@ Create_Transform_from_Points(double llx, double lly, double lrx, double lry,
|
|
258
388
|
}
|
259
389
|
|
260
390
|
|
391
|
+
/* Read the image here ?*/
|
392
|
+
int
|
393
|
+
c_private_register_jpg(OBJ_PTR fmkr, FM *p, char *filename,
|
394
|
+
int width, int height,
|
395
|
+
int mask_obj_num, int *ierr)
|
396
|
+
{
|
397
|
+
JPG_Info *xo = (JPG_Info *)calloc(1,sizeof(JPG_Info));
|
398
|
+
xo->xobj_subtype = JPG_SUBTYPE;
|
399
|
+
xo->next = xobj_list;
|
400
|
+
xobj_list = (XObject_Info *)xo;
|
401
|
+
xo->xo_num = next_available_xo_number++;
|
402
|
+
xo->obj_num = next_available_object_number++;
|
403
|
+
xo->filename = ALLOC_N_char(strlen(filename)+1);
|
404
|
+
strcpy(xo->filename, filename);
|
405
|
+
xo->width = width;
|
406
|
+
xo->height = height;
|
407
|
+
xo->mask_obj_num = mask_obj_num;
|
408
|
+
return xo->obj_num;
|
409
|
+
}
|
410
|
+
|
411
|
+
|
261
412
|
static void
|
262
|
-
|
413
|
+
Expand_Array(OBJ_PTR image_destination, double *dest, int *ierr)
|
263
414
|
{
|
264
415
|
int len = Array_Len(image_destination,ierr);
|
265
416
|
if (*ierr != 0) return;
|
@@ -272,58 +423,31 @@ Get_Image_Dest(FM *p, OBJ_PTR image_destination, double *dest, int *ierr)
|
|
272
423
|
for (i = 0; i < 6; i++) {
|
273
424
|
OBJ_PTR entry = Array_Entry(image_destination, i, ierr);
|
274
425
|
if (*ierr != 0) return;
|
275
|
-
|
276
|
-
dest[i] = convert_figure_to_output_x(p,Number_to_double(entry, ierr));
|
277
|
-
else
|
278
|
-
dest[i] = convert_figure_to_output_y(p,Number_to_double(entry, ierr));
|
426
|
+
dest[i] = Number_to_double(entry, ierr);
|
279
427
|
if (*ierr != 0) return;
|
280
428
|
}
|
281
429
|
}
|
282
430
|
|
283
|
-
|
284
|
-
static void
|
285
|
-
Show_JPEG(FM *p, char *filename, int width, int height, double *dest,
|
286
|
-
int subtype, int mask_obj_num)
|
287
|
-
{
|
288
|
-
JPG_Info *xo = (JPG_Info *)calloc(1,sizeof(JPG_Info));
|
289
|
-
xo->xobj_subtype = subtype;
|
290
|
-
double llx = dest[0], lly = dest[1], lrx = dest[2], lry = dest[3],
|
291
|
-
ulx = dest[4], uly = dest[5];
|
292
|
-
double a, b, c, d, e, f; // the transform to position the image
|
293
|
-
xo->next = xobj_list;
|
294
|
-
xobj_list = (XObject_Info *)xo;
|
295
|
-
xo->xo_num = next_available_xo_number++;
|
296
|
-
xo->obj_num = next_available_object_number++;
|
297
|
-
xo->filename = ALLOC_N_char(strlen(filename)+1);
|
298
|
-
strcpy(xo->filename, filename);
|
299
|
-
xo->width = width;
|
300
|
-
xo->height = height;
|
301
|
-
xo->mask_obj_num = mask_obj_num;
|
302
|
-
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
303
|
-
&a, &b, &c, &d, &e, &f);
|
304
|
-
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
305
|
-
a, b, c, d, e, f, xo->xo_num);
|
306
|
-
update_bbox(p, llx, lly);
|
307
|
-
update_bbox(p, lrx, lry);
|
308
|
-
update_bbox(p, ulx, uly);
|
309
|
-
update_bbox(p, lrx+ulx-llx, lry+uly-lly);
|
310
|
-
}
|
311
|
-
|
312
|
-
|
313
431
|
void
|
314
432
|
c_private_show_jpg(OBJ_PTR fmkr, FM *p, char *filename,
|
315
433
|
int width, int height, OBJ_PTR image_destination,
|
316
434
|
int mask_obj_num, int *ierr)
|
317
435
|
{
|
318
436
|
double dest[6];
|
437
|
+
int ref;
|
319
438
|
if (constructing_path) {
|
320
439
|
RAISE_ERROR("Sorry: must finish with current path before "
|
321
440
|
"calling show_jpg", ierr);
|
322
441
|
return;
|
323
442
|
}
|
324
|
-
|
443
|
+
ref = c_private_register_jpg(fmkr, p, filename, width, height,
|
444
|
+
mask_obj_num, *ierr);
|
445
|
+
Expand_Array(image_destination, dest, ierr);
|
325
446
|
if (*ierr != 0) return;
|
326
|
-
|
447
|
+
|
448
|
+
c_private_show_image_from_ref(fmkr, p, ref, dest[0], dest[1],
|
449
|
+
dest[2], dest[3], dest[4], dest[5],
|
450
|
+
ierr);
|
327
451
|
}
|
328
452
|
|
329
453
|
|
@@ -465,7 +589,29 @@ c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
|
465
589
|
double uly, bool interpolate, bool reversed,
|
466
590
|
int w, int h, unsigned char* data, long len,
|
467
591
|
OBJ_PTR mask_min, OBJ_PTR mask_max, OBJ_PTR hivalue,
|
468
|
-
OBJ_PTR lookup_data, int mask_obj_num, int
|
592
|
+
OBJ_PTR lookup_data, int mask_obj_num, int components,
|
593
|
+
const char * filters,
|
594
|
+
int *ierr)
|
595
|
+
{
|
596
|
+
int ref = c_private_register_image(fmkr, p, image_type,
|
597
|
+
interpolate, reversed,
|
598
|
+
w, h, data, len, mask_min,
|
599
|
+
mask_max, hivalue, lookup_data,
|
600
|
+
mask_obj_num, components, filters, ierr);
|
601
|
+
if (mask_obj_num != -1)
|
602
|
+
c_private_show_image_from_ref(fmkr, p, ref, llx, lly,
|
603
|
+
lrx, lry, ulx, uly, ierr);
|
604
|
+
return Integer_New(ref);
|
605
|
+
}
|
606
|
+
|
607
|
+
int
|
608
|
+
c_private_register_image(OBJ_PTR fmkr, FM *p, int image_type,
|
609
|
+
bool interpolate, bool reversed,
|
610
|
+
int w, int h, unsigned char* data, long len,
|
611
|
+
OBJ_PTR mask_min, OBJ_PTR mask_max, OBJ_PTR hivalue,
|
612
|
+
OBJ_PTR lookup_data, int mask_obj_num, int components,
|
613
|
+
const char * filters,
|
614
|
+
int *ierr)
|
469
615
|
{
|
470
616
|
unsigned char *lookup = NULL;
|
471
617
|
int value_mask_min = 256, value_mask_max = 256, lookup_len = 0, hival = 0;
|
@@ -483,12 +629,6 @@ c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
|
483
629
|
if (*ierr != 0) RETURN_NIL;
|
484
630
|
}
|
485
631
|
|
486
|
-
llx = convert_figure_to_output_x(p, llx);
|
487
|
-
lly = convert_figure_to_output_y(p, lly);
|
488
|
-
lrx = convert_figure_to_output_x(p, lrx);
|
489
|
-
lry = convert_figure_to_output_y(p, lry);
|
490
|
-
ulx = convert_figure_to_output_x(p, ulx);
|
491
|
-
uly = convert_figure_to_output_y(p, uly);
|
492
632
|
|
493
633
|
Sampled_Info *xo = (Sampled_Info *)calloc(1, sizeof(Sampled_Info));
|
494
634
|
xo->xobj_subtype = SAMPLED_SUBTYPE;
|
@@ -502,8 +642,16 @@ c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
|
502
642
|
xo->length = len;
|
503
643
|
xo->interpolate = interpolate;
|
504
644
|
xo->reversed = reversed;
|
645
|
+
xo->components = components;
|
505
646
|
memcpy(xo->image_data, data, len);
|
506
647
|
xo->image_type = image_type;
|
648
|
+
if(filters) {
|
649
|
+
int len = strlen(filters) + 1;
|
650
|
+
xo->filters = calloc(1, len);
|
651
|
+
memcpy(xo->filters, filters, len);
|
652
|
+
}
|
653
|
+
else
|
654
|
+
xo->filters = NULL;
|
507
655
|
if (image_type != COLORMAP_IMAGE) xo->lookup = NULL;
|
508
656
|
else {
|
509
657
|
if ((hival+1)*3 > lookup_len) {
|
@@ -523,17 +671,59 @@ c_private_show_image(OBJ_PTR fmkr, FM *p, int image_type, double llx,
|
|
523
671
|
xo->value_mask_min = value_mask_min;
|
524
672
|
xo->value_mask_max = value_mask_max;
|
525
673
|
xo->mask_obj_num = mask_obj_num;
|
526
|
-
|
527
|
-
|
528
|
-
|
674
|
+
return xo->obj_num;
|
675
|
+
}
|
676
|
+
|
677
|
+
/* Goes through the xobject list and find the one whose object number
|
678
|
+
matches the one given, and returns the Xobject number. -1 if not
|
679
|
+
found. */
|
680
|
+
|
681
|
+
int Find_XObjRef(int ref)
|
682
|
+
{
|
683
|
+
XObject_Info * info = xobj_list;
|
684
|
+
while(1) {
|
685
|
+
if(info->obj_num == ref)
|
686
|
+
return info->xo_num;
|
687
|
+
info = info->next;
|
688
|
+
if(! info)
|
689
|
+
break;
|
690
|
+
}
|
691
|
+
return -1;
|
692
|
+
}
|
693
|
+
|
694
|
+
void
|
695
|
+
c_private_show_image_from_ref(OBJ_PTR fmkr, FM *p, int ref, double llx,
|
696
|
+
double lly, double lrx, double lry, double ulx,
|
697
|
+
double uly,
|
698
|
+
int *ierr)
|
699
|
+
{
|
700
|
+
if (constructing_path) {
|
701
|
+
RAISE_ERROR("Sorry: must finish with current path before calling "
|
702
|
+
"show_image", ierr);
|
703
|
+
return;
|
704
|
+
}
|
705
|
+
|
706
|
+
double a, b, c, d, e, f; // the transform to position the image
|
707
|
+
int xo_num = Find_XObjRef(ref);
|
708
|
+
if(xo_num < 0) {
|
709
|
+
RAISE_ERROR_i("Could not find image PDF object %d", ref,
|
710
|
+
ierr);
|
711
|
+
return;
|
712
|
+
}
|
713
|
+
|
714
|
+
llx = convert_figure_to_output_x(p, llx);
|
715
|
+
lly = convert_figure_to_output_y(p, lly);
|
716
|
+
lrx = convert_figure_to_output_x(p, lrx);
|
717
|
+
lry = convert_figure_to_output_y(p, lry);
|
718
|
+
ulx = convert_figure_to_output_x(p, ulx);
|
719
|
+
uly = convert_figure_to_output_y(p, uly);
|
720
|
+
|
529
721
|
Create_Transform_from_Points(llx, lly, lrx, lry, ulx, uly,
|
530
722
|
&a, &b, &c, &d, &e, &f);
|
531
723
|
fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /XObj%i Do Q\n",
|
532
|
-
a, b, c, d, e, f,
|
724
|
+
a, b, c, d, e, f, xo_num);
|
533
725
|
update_bbox(p, llx, lly);
|
534
726
|
update_bbox(p, lrx, lry);
|
535
727
|
update_bbox(p, ulx, uly);
|
536
728
|
update_bbox(p, lrx+ulx-llx, lry+uly-lly);
|
537
|
-
return Integer_New(xo->obj_num);
|
538
729
|
}
|
539
|
-
|