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.
@@ -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
- Tioga 1.17 provides all the necessary fixes to have it run on
26
- windows, so now we also support the Redmond operating system (works
27
- with the ProTeXt LaTeX distribution).
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. *This
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
- a = StringValueCStr(pre);
5746
- double c = strtod(a, &b);
5747
- if(b == a)
5748
- c = def;
5749
- if(col >= nb_vectors) {
5750
- nb_vectors++;
5751
- /* We need to create a new vector */
5752
- if(col >= current_size) { /* Increase the available size */
5753
- current_size += 5;
5754
- REALLOC_N(vectors, double * , current_size);
5755
- }
5756
-
5757
- double * vals = vectors[col] = ALLOC_N(double, allocated_size);
5758
- /* Filling it with the default value */
5759
- for(i = 0; i < index; i++) {
5760
- vals[i] = def;
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
- vectors[col][index] = def;
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
- REALLOC_N(vectors[col], double, allocated_size);
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
- rb_ary_store(ary, i, make_dvector_from_data(cDvector, index, vectors[i]));
5782
- /* And free the memory */
5783
- free(vectors[i]);
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, "1");
344
- else if (exponent == 1) strcpy(buff, "10");
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/Filter /FlateDecode\n\t/Interpolate %s\n",
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 8\n");
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 8\n");
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 8\n");
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 8\n");
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
- new_len = (xo->length * 11)/10 + 100;
231
- buffer = ALLOC_N_unsigned_char(new_len);
232
- if (do_flate_compress(buffer, &new_len, image_data, xo->length)
233
- != FLATE_OK) {
234
- free(buffer);
235
- RAISE_ERROR("Error compressing image data", ierr);
236
- return;
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(buffer, 1, new_len, OF) < new_len) {
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
- free(buffer);
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
- Get_Image_Dest(FM *p, OBJ_PTR image_destination, double *dest, int *ierr)
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
- if (i % 2 == 0)
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
- Get_Image_Dest(p, image_destination, dest, ierr);
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
- Show_JPEG(p, filename, width, height, dest, JPG_SUBTYPE, mask_obj_num);
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 *ierr)
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
- if (mask_obj_num == -1)
527
- return Integer_New(xo->obj_num); // this image is being used as
528
- // an opacity mask
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, xo->xo_num);
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
-