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