1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8 /*
9 * $Header: /src/master/dx/src/exec/dxmods/_helper_jea.c,v 1.8 2003/07/11 05:50:33 davidt Exp $
10 */
11
12 #include <dxconfig.h>
13
14
15 #include <string.h>
16 #include <math.h>
17 #include <dx/dx.h>
18 #include "_helper_jea.h"
19 #include <fcntl.h>
20
21 #define ERROR_SECTION if ( DXGetError() == ERROR_NONE ) \
22 DXDebug ( "I0D", "No error set at %s:%d", __FILE__,__LINE__)
23
24 /*
25 * These data Must align with defined 'Component_Type' at all times.
26 * Never!: access by index not of type 'Component_Type'.
27 * Always!: access with the Component_Type_pos macro.
28 *
29 * XXX - Be prepared for shape arrays for when rank>1.
30 * XXX - Notion of Class/SubClass: *_CONNECTIONS_COMP "dep" POSITIONS_3D_COMP
31 * is overconstrained. Perhaps procedural string matching?
32 */
33 static struct _comp_data_rec_type
34 {
35 Component_Type self;
36 char *name;
37 Component_Type dependancy;
38 Component_Type reference;
39 char *element_type;
40 Type type;
41 Category cat;
42 int rank;
43 int shape;
44 int reg_dims;
45 }
46 #if 0
47 comp_data [ Component_Type_size ]
48 #else
49 /* AIX RS6000 on odd release renumbers things */
50 comp_data [ ]
51 #endif
52 = {
53 { POSITIONS_2D_COMP,
54 "positions",
55 NULL_COMP, NULL_COMP, NULL,
56 TYPE_FLOAT, CATEGORY_REAL, 1, 2, 2 },
57
58 { POSITIONS_3D_COMP,
59 "positions",
60 NULL_COMP, NULL_COMP, NULL,
61 TYPE_FLOAT, CATEGORY_REAL, 1, 3, 3 },
62 /*
63 * Rank 1 shape 1 is more a vector, length 1 than a scalar,
64 * which is rank 0. Data is scalar and therefore of rank 0.
65 */
66 { POINT_DATA_COMP,
67 "data",
68 POSITIONS_3D_COMP, NULL_COMP, NULL,
69 TYPE_FLOAT, CATEGORY_REAL, 0, 0, 1 },
70
71 { POINT_COLORS_COMP,
72 "colors",
73 POSITIONS_3D_COMP, NULL_COMP, NULL,
74 TYPE_FLOAT, CATEGORY_REAL, 1, 3, 3 },
75
76 { POINT_NORMALS_COMP,
77 "normals",
78 POSITIONS_3D_COMP, NULL_COMP, NULL,
79 TYPE_FLOAT, CATEGORY_REAL, 1, 3, 3 },
80
81 { TETRA_NEIGHBORS_COMP,
82 "neighbors",
83 TETRA_CONNECTIONS_COMP, NULL_COMP, NULL,
84 TYPE_INT, CATEGORY_REAL, 1, 4, 4 },
85
86 /* NEW */
87
88 { CUBE_NEIGHBORS_COMP,
89 "neighbors",
90 CUBE_CONNECTIONS_COMP, NULL_COMP, NULL,
91 TYPE_INT, CATEGORY_REAL, 1, 6, 6 },
92
93 /* XXX - Note that
94 "connections" "ref" 3D "positions"
95 is overly restrictive.
96 Current plan is to make an unconstrained
97 superclass to use in the ref slot. */
98
99 { LINE_CONNECTIONS_COMP,
100 "connections",
101 NULL_COMP, POSITIONS_3D_COMP, "lines",
102 TYPE_INT, CATEGORY_REAL, 1, 2, 1 },
103
104 { QUAD_CONNECTIONS_COMP,
105 "connections",
106 NULL_COMP, POSITIONS_3D_COMP, "quads",
107 TYPE_INT, CATEGORY_REAL, 1, 4, 2 },
108
109 { TRIANGLE_CONNECTIONS_COMP,
110 "connections",
111 NULL_COMP, POSITIONS_3D_COMP, "triangles",
112 TYPE_INT, CATEGORY_REAL, 1, 3, 3 },
113
114 { CUBE_CONNECTIONS_COMP,
115 "connections",
116 NULL_COMP, POSITIONS_3D_COMP, "cubes",
117 TYPE_INT, CATEGORY_REAL, 1, 8, 3 },
118
119 { TETRA_CONNECTIONS_COMP,
120 "connections",
121 NULL_COMP, POSITIONS_3D_COMP, "tetrahedra",
122 TYPE_INT, CATEGORY_REAL, 1, 4, 4 }
123 };
124
125 /*------------------------------------------------*
126 * *
127 * Guide to seeing connectivity data: *
128 * vertex number chart *
129 * *
130 * for 2D: observer is in front of the page *
131 * for 3D: lower left is closest to the observer. *
132 * *
133 *------------------------------------------------*
134 * *
135 * line: *
136 * p --- q 0 --- 1 *
137 * *
138 *------------------------------------------------*
139 * *
140 * triangle: *
141 * p 0 *
142 * / \ / \ *
143 * / \ / \ *
144 * q --- r 1 --- 2 *
145 * *
146 *------------------------------------------------*
147 * *
148 * quad(rangle): *
149 * p --- q 0 --- 1 *
150 * | | | | *
151 * | | | | *
152 * r --- s 2 --- 3 *
153 * *
154 *------------------------------------------------*
155 * *
156 * tetrahedron: *
157 * p -s 0 -3 *
158 * / \ | / \ | *
159 * / \| / \| *
160 * q --- r 1 --- 2 *
161 * *
162 *------------------------------------------------*
163 * *
164 * cube: *
165 * p --- q 0 --- 1 *
166 * /| /| /| /| *
167 * r --- s | 2 --- 3 | *
168 * | | | | | | | | *
169 * | t --| u | 4 --| 5 *
170 * |/ |/ |/ |/ *
171 * v --- w 6 --- 7 *
172 * *
173 *------------------------------------------------*/
174
175 /* Decomposition of Connective Elements:
176 *
177 * (Names below are Types as from <basic.h>)
178 *
179 * Line -> Two Points
180 * Quadrilateral -> Four Lines
181 * Triangle -> Three Lines
182 * Cube -> Six Quadrilaterals
183 * Tetrahedron -> Four Triangles
184 */
185 struct _connect_data_rec_type
186 {
187 Component_Type self;
188 int dimensionality;
189 Component_Type degenerates_to;
190 int ndegens;
191 int degensiz;
192 int connect[6][4];
193 };
194
195 #if 0
196 static struct _connect_data_rec_type
197 connect_data [ Connective_Component_Type_size ]
198 =
199 { { LINE_CONNECTIONS_COMP, 1, POSITIONS_3D_COMP, 2, 1,
200 { { 0, -1, -1, -1 },
201 { 1, -1, -1, -1 },
202 { -1, -1, -1, -1 },
203 { -1, -1, -1, -1 },
204 { -1, -1, -1, -1 },
205 { -1, -1, -1, -1 } } },
206 { QUAD_CONNECTIONS_COMP, 2, LINE_CONNECTIONS_COMP, 4, 2,
207 { { 0, 1, -1, -1 },
208 { 1, 3, -1, -1 },
209 { 3, 2, -1, -1 },
210 { 2, 0, -1, -1 },
211 { -1, -1, -1, -1 },
212 { -1, -1, -1, -1 } } },
213 { TRIANGLE_CONNECTIONS_COMP, 2, LINE_CONNECTIONS_COMP, 3, 2,
214 { { 0, 1, -1, -1 },
215 { 1, 2, -1, -1 },
216 { 2, 0, -1, -1 },
217 { -1, -1, -1, -1 },
218 { -1, -1, -1, -1 },
219 { -1, -1, -1, -1 } } },
220 { CUBE_CONNECTIONS_COMP, 3, QUAD_CONNECTIONS_COMP, 6, 4,
221 /* Changed */
222 { { 1, 0, 3, 2 },
223 { 4, 5, 6, 7 },
224 { 0, 1, 4, 5 },
225 { 2, 6, 3, 7 },
226 { 0, 4, 2, 6 },
227 { 1, 3, 5, 7 } } },
228 { TETRA_CONNECTIONS_COMP, 3, TRIANGLE_CONNECTIONS_COMP, 4, 3,
229 { { 1, 3, 2, -1 },
230 { 0, 2, 3, -1 },
231 { 0, 3, 1, -1 },
232 { 0, 1, 2, -1 },
233 { -1, -1, -1, -1 },
234 { -1, -1, -1, -1 } } } };
235 #endif
236
237 #if 0
238 static Error _inspect ( )
239 {
240 DXMessage
241 ( "Component_Type: first %d, last %d, size %d",
242 Component_Type_first,
243 Component_Type_last,
244 Component_Type_size );
245
246 DXMessage
247 ( "Component_Type: pos(first) %d, pos(last) %d",
248 Component_Type_pos ( Component_Type_first ),
249 Component_Type_pos ( Component_Type_last ) );
250
251 DXMessage
252 ( "Component_Type: sizeof rec %d, sizeof array %d",
253 sizeof ( comp_data ),
254 sizeof ( struct _comp_data_rec_type ) );
255
256 DXMessage
257 ( "Connective_Component_Type: first %d, last %d, size %d",
258 Connective_Component_Type_first,
259 Connective_Component_Type_last,
260 Connective_Component_Type_size );
261
262 DXMessage
263 ( "Connective_Component_Type: pos(first) %d, pos(last) %d",
264 Connective_Component_Type_pos ( Connective_Component_Type_first ),
265 Connective_Component_Type_pos ( Connective_Component_Type_last ) );
266
267 DXMessage
268 ( "Connective_Component_Type: sizeof rec %d, sizeof array %d",
269 sizeof ( connect_data ),
270 sizeof ( struct _connect_data_rec_type ) );
271
272 return OK;
273 }
274 #endif
275
276
277 /*----------------------------- Begin Types section -------------------------*/
278
_dxf_ClassName(Class class)279 char * _dxf_ClassName ( Class class )
280 {
281 switch ( class )
282 {
283 case CLASS_DELETED: return "CLASS_DELETED";
284 case CLASS_MIN: return "CLASS_MIN";
285 case CLASS_OBJECT: return "CLASS_OBJECT";
286 case CLASS_PRIVATE: return "CLASS_PRIVATE";
287 case CLASS_STRING: return "CLASS_STRING";
288 case CLASS_FIELD: return "CLASS_FIELD";
289 case CLASS_GROUP: return "CLASS_GROUP";
290 case CLASS_SERIES: return "CLASS_SERIES";
291 case CLASS_COMPOSITEFIELD: return "CLASS_COMPOSITEFIELD";
292 case CLASS_ARRAY: return "CLASS_ARRAY";
293 case CLASS_REGULARARRAY: return "CLASS_REGULARARRAY";
294 case CLASS_PATHARRAY: return "CLASS_PATHARRAY";
295 case CLASS_PRODUCTARRAY: return "CLASS_PRODUCTARRAY";
296 case CLASS_MESHARRAY: return "CLASS_MESHARRAY";
297 case CLASS_INTERPOLATOR: return "CLASS_INTERPOLATOR";
298 case CLASS_FIELDINTERPOLATOR: return "CLASS_FIELDINTERPOLATOR";
299 case CLASS_GROUPINTERPOLATOR: return "CLASS_GROUPINTERPOLATOR";
300 case CLASS_LINESRR1DINTERPOLATOR: return "CLASS_LINESRR1DINTERPOLATOR";
301 case CLASS_LINESRI1DINTERPOLATOR: return "CLASS_LINESRI1DINTERPOLATOR";
302 case CLASS_QUADSRR2DINTERPOLATOR: return "CLASS_QUADSRR2DINTERPOLATOR";
303 case CLASS_QUADSII2DINTERPOLATOR: return "CLASS_QUADSII2DINTERPOLATOR";
304 case CLASS_TRISRI2DINTERPOLATOR: return "CLASS_TRISRI2DINTERPOLATOR";
305 case CLASS_CUBESRRINTERPOLATOR: return "CLASS_CUBESRRINTERPOLATOR";
306 case CLASS_CUBESIIINTERPOLATOR: return "CLASS_CUBESIIINTERPOLATOR";
307 case CLASS_TETRASINTERPOLATOR: return "CLASS_TETRASINTERPOLATOR";
308 case CLASS_GROUPITERATOR: return "CLASS_GROUPITERATOR";
309 case CLASS_ITEMITERATOR: return "CLASS_ITEMITERATOR";
310 case CLASS_XFORM: return "CLASS_XFORM";
311 case CLASS_SCREEN: return "CLASS_SCREEN";
312 case CLASS_CLIPPED: return "CLASS_CLIPPED";
313 case CLASS_CAMERA: return "CLASS_CAMERA";
314 case CLASS_LIGHT: return "CLASS_LIGHT";
315 case CLASS_MAX: return "CLASS_MAX";
316 default: return "*** Unknown Class ***";
317 }
318 }
319
320
321 /*------------------------------ End Types section --------------------------*/
322
323
324 /*------------------------ Begin Component Access section -------------------*/
325
326 /* Extern routine. Consult the file header */
_dxf_NewComponentArray(Component_Type comp_type,int * count,Pointer origin,Pointer delta)327 Array _dxf_NewComponentArray ( Component_Type comp_type,
328 int *count,
329 Pointer origin,
330 Pointer delta )
331 {
332 Array array;
333 int position = Component_Type_pos ( comp_type );
334
335 DXASSERT ( comp_type != NULL_COMP );
336 DXASSERT ( ( position >= 0 ) && ( position < Component_Type_size ) );
337
338 if ( count && origin ) /* Regularity was requested */
339 switch ( comp_type )
340 {
341 /*
342 * Note that Category and rank are missing from DXNewRegularArray.
343 * Assumptions are CATEGORY_REAL and RANK=1.
344 * Special handling:
345 * Data becomes shape 1 to adapt to this restriction.
346 * (Scalar as rank 0 becomes vector length 1)
347 */
348 case POINT_DATA_COMP:
349 DXASSERTGOTO ( delta != NULL );
350 array = (Array) DXNewRegularArray ( comp_data [ position ].type,
351 1,
352 *count, origin, delta );
353 break;
354 case POINT_COLORS_COMP:
355 DXASSERTGOTO ( delta != NULL );
356 array = (Array) DXNewRegularArray ( comp_data [ position ].type,
357 comp_data [ position ].shape,
358 *count, origin, delta );
359 break;
360 case POSITIONS_2D_COMP:
361 case POSITIONS_3D_COMP:
362 DXASSERTGOTO ( delta != NULL );
363 /* be aware that count, origin, delta contain
364 a number of elements equalling shape */
365 array = DXMakeGridPositionsV ( comp_data [ position ].shape,
366 count,
367 (float *)origin,
368 (float *)delta );
369 break;
370 case CUBE_CONNECTIONS_COMP:
371 case QUAD_CONNECTIONS_COMP:
372 /* be aware that count, origin contain
373 a number of elements equalling shape */
374 array = DXMakeGridConnectionsV
375 ( comp_data [ position ].reg_dims, count );
376 array = (Array) DXSetMeshOffsets
377 ( (MeshArray) array, (int *)origin );
378 break;
379 default:
380 DXSetError
381 ( ERROR_NOT_IMPLEMENTED,
382 "Cannot allocate array as regular (%d)",
383 comp_type );
384 return ERROR;
385 }
386 else
387 {
388 array = DXNewArray ( comp_data [ position ].type,
389 comp_data [ position ].cat,
390 comp_data [ position ].rank,
391 comp_data [ position ].shape );
392 if ( count )
393 array = DXAddArrayData ( array, 0, *count, NULL );
394 }
395
396 /* XXX - note that the attributes cannot be inserted
397 above the array in the field as
398 we do not have the parent field object to set them in. */
399
400 if ( !array )
401 goto error;
402 else
403 return array;
404
405 error:
406 ERROR_SECTION;
407 return ERROR;
408 }
409
410
411 /* Extern routine. Consult the file header */
_dxf_GetComponentData(Object in_object,Component_Type comp_type,int * count,Pointer origin,Pointer delta,Pointer * pointer)412 Error _dxf_GetComponentData ( Object in_object,
413 Component_Type comp_type,
414 int *count, /* length */
415 Pointer origin,
416 Pointer delta,
417 Pointer *pointer )
418 {
419 Array array;
420 Object attribute;
421 Pointer ptr = NULL;
422
423 int rank;
424 int position = Component_Type_pos ( comp_type );
425
426 /* NULL pointer -> regular; else irregular */
427 if ( pointer ) *pointer = NULL;
428
429 DXASSERT ( comp_type != NULL_COMP );
430 DXASSERT ( ( position >= 0 ) && ( position < Component_Type_size ) );
431 DXASSERT ( count != NULL );
432
433 if ( !in_object ) DXErrorReturn ( ERROR_MISSING_DATA, "Null Object" );
434
435 *count = 0;
436
437 if ( ( array = (Array) DXGetComponentValue
438 ( (Field)in_object,
439 comp_data [ position ].name ) ) == NULL )
440 DXErrorGoto2
441 ( ERROR_MISSING_DATA,
442 "\"%s\" component absent.", comp_data [ position ].name )
443
444 if ( comp_data [ position ].element_type != NULL )
445 {
446 if ( ( attribute = DXGetComponentAttribute
447 ( (Field)in_object,
448 comp_data [ position ].name,
449 "element type" ) ) == NULL )
450 ErrorGotoPlus1
451 ( ERROR_DATA_INVALID,
452 "\"%s\" component is missing the \"element type\" attribute",
453 comp_data [ position ].name )
454
455 else if ( DXGetObjectClass ( attribute ) != CLASS_STRING )
456
457 ErrorGotoPlus1
458 ( ERROR_DATA_INVALID,
459 "\"%s\" component \"element type\" attribute is not a string",
460 comp_data [ position ].name )
461
462 else if ( strcmp
463 ( DXGetString
464 ( (String)attribute ),
465 comp_data [ position ].element_type ) != 0 )
466 ErrorGotoPlus3
467 ( ERROR_DATA_INVALID,
468 "the \"%s\" component \"element type\" is \"%s\", not \"%s\"",
469 comp_data [ position ].name,
470 DXGetString ( (String)attribute ),
471 comp_data[ position ].element_type )
472 }
473
474 /*
475 * Elaborate check just to say: is the request scalar?
476 */
477 if ( ( comp_data[ position ].rank == 0 )
478 ||
479 ( ( comp_data[ position ].rank == 1 )
480 &&
481 ( comp_data[ position ].shape == 1 ) ) )
482 {
483 if ( !DXTypeCheck ( array,
484 comp_data [ position ].type,
485 comp_data [ position ].cat,
486 0 ) )
487 {
488 DXResetError();
489 if ( !DXTypeCheck ( array,
490 comp_data [ position ].type,
491 comp_data [ position ].cat,
492 1, 1 ) )
493 ErrorGotoPlus1
494 ( ERROR_DATA_INVALID,
495 "\"%s\" component failed scalar type check",
496 comp_data [ position ].name )
497 }
498 }
499 else
500 if ( !DXTypeCheck ( array,
501 comp_data [ position ].type,
502 comp_data [ position ].cat,
503 comp_data [ position ].rank,
504 comp_data [ position ].shape ) )
505 ErrorGotoPlus1
506 ( ERROR_DATA_INVALID,
507 "\"%s\" component failed type check",
508 comp_data [ position ].name )
509
510 if ( !DXGetArrayInfo ( array, count, NULL, NULL, NULL, NULL ) )
511 goto error;
512
513 if ( origin ) /* Regularity was requested */
514 switch ( comp_type )
515 {
516 /* Recall that ranks and shapes were already TypeChecked */
517 case POINT_DATA_COMP:
518 case POINT_COLORS_COMP:
519 DXASSERTGOTO ( delta != NULL );
520 if ( ( DXGetArrayClass ( array ) == CLASS_REGULARARRAY )
521 &&
522 DXGetRegularArrayInfo
523 ( (RegularArray)array, count, origin, delta ) ) {
524 if ( pointer ) *pointer = NULL;
525 return OK;
526 }
527 break;
528 case POSITIONS_2D_COMP:
529 case POSITIONS_3D_COMP:
530 DXASSERTGOTO ( delta != NULL );
531 if ( DXQueryGridPositions ( array,
532 &rank, count,
533 (float *)origin, (float *)delta ) ) {
534 if ( pointer ) *pointer = NULL;
535 return OK;
536 }
537 break;
538 case QUAD_CONNECTIONS_COMP:
539 case CUBE_CONNECTIONS_COMP:
540 if ( ( DXGetArrayClass ( array ) == CLASS_MESHARRAY )
541 &&
542 DXQueryGridConnections ( array, &rank, count )
543 &&
544 DXGetMeshOffsets ( (MeshArray) array,
545 (int *) origin ) ) {
546 if ( pointer ) *pointer = NULL;
547 return OK;
548 }
549 break;
550 default:
551 break;
552 /* Expand in any case */
553 }
554
555 #if 0
556
557 else /* Regularity was NOT requested */
558
559 #define WARN_EXPAND \
560 DXDebug ( "D", "About to expand regular data using DXGetArrayData" )
561 switch ( comp_type )
562 {
563 case POINT_DATA_COMP:
564 case POINT_COLORS_COMP:
565 if ( ( DXGetArrayClass ( array ) == CLASS_REGULARARRAY )
566 &&
567 DXGetRegularArrayInfo
568 ( (RegularArray)array, NULL, NULL, NULL ) )
569 WARN_EXPAND;
570 break;
571 case POSITIONS_2D_COMP:
572 case POSITIONS_3D_COMP:
573 if ( ( DXGetArrayClass ( array ) == CLASS_PRODUCTARRAY )
574 &&
575 ( DXGetProductArrayInfo ( (ProductArray)array, NULL, NULL )
576 ||
577 DXQueryGridPositions ( array, NULL, NULL, NULL, NULL ) ) )
578 WARN_EXPAND;
579 break;
580 case QUAD_CONNECTIONS_COMP:
581 case CUBE_CONNECTIONS_COMP:
582 if ( ( DXGetArrayClass ( array ) == CLASS_MESHARRAY )
583 &&
584 ( DXGetMeshArrayInfo ( (MeshArray)array, NULL, NULL )
585 ||
586 DXQueryGridConnections ( array, NULL, NULL ) ) )
587 WARN_EXPAND;
588 break;
589 default:
590 break;
591 }
592 #endif
593
594 if ( ERROR == ( ptr = DXGetArrayData ( array ) ) ) {
595 if ( DXGetError() != ERROR_NONE )
596 goto error;
597 else
598 ErrorGotoPlus1
599 ( ERROR_MISSING_DATA,
600 "\"%s\" component is null", comp_data [ position ].name )
601 }
602
603 if ( pointer ) *pointer = ptr;
604 return OK;
605
606 error:
607 ERROR_SECTION;
608 return ERROR;
609 }
610
611 /*------------------------- End Component Access section --------------------*/
612
613
614 /*----------------------------- Begin Array section -------------------------*/
615
616
_dxf_CopyArray_jea(Array in,enum _dxd_copy copy)617 Array _dxf_CopyArray_jea ( Array in, enum _dxd_copy copy )
618 {
619 Array out = NULL;
620 Type type;
621 Category category;
622 int rank;
623 int *shape = NULL;
624
625 DXASSERTGOTO ( in != NULL );
626 DXASSERTGOTO ( copy == COPY_HEADER );
627
628 /*
629 * De Facto rank limits:
630 * Nancy: Import: 15 -> 50; Donna: Construct: 32; Bruce: libdx: 100
631 */
632
633 if ( !DXGetArrayInfo ( in, NULL, NULL, NULL, &rank, NULL ) )
634 goto error;
635
636 if ( rank == 0 )
637 {
638 if ( !DXGetArrayInfo ( in, NULL, &type, &category, &rank, NULL ) )
639 goto error;
640 }
641 else
642 {
643 if ( ( ERROR == ( shape = (int *) DXAllocateLocal
644 ( rank * sizeof(int) ) ) )
645 ||
646 !DXGetArrayInfo ( in, NULL, &type, &category, &rank, shape ) )
647 goto error;
648 }
649
650 if ( ERROR == ( out = DXNewArrayV ( type, category, rank, shape ) ) )
651 goto error;
652
653 DXFree ( (Pointer) shape ); shape = NULL;
654
655 return out;
656
657 error:
658 ERROR_SECTION;
659
660 DXDelete ( (Object) out ); out = NULL;
661 DXFree ( (Pointer) shape ); shape = NULL;
662
663 return ERROR;
664 }
665
666 /*------------------------------ End Array section --------------------------*/
667
668 /*----------------------------- Begin Group section -------------------------*/
669
670
671 static
672 /* The initial value of position is 0 */
673 /* XXX Move up */
_flatten_hierarchy(Object in,CompositeField out,int * position)674 Object _flatten_hierarchy ( Object in, CompositeField out, int *position )
675 {
676 int i;
677 Object member;
678
679 DXASSERTGOTO ( in && out && position );
680
681 switch ( DXGetObjectClass ( in ) )
682 {
683 case CLASS_FIELD:
684 if ( !DXSetEnumeratedMember ( (Group)out, *position, in ) )
685 goto error;
686
687 (*position)++;
688 break;
689
690 case CLASS_GROUP:
691
692 if ( DXGetGroupClass ( (Group) in ) != CLASS_COMPOSITEFIELD )
693 DXErrorGoto
694 ( ERROR_DATA_INVALID, "Illegal member in Composite Field" );
695
696 for ( i = 0;
697 (member=DXGetEnumeratedMember ( (Group)in, i, NULL ));
698 i++ )
699 if ( !_flatten_hierarchy ( member, out, position ) )
700 goto error;
701 break;
702
703 default:
704 DXErrorGoto ( ERROR_DATA_INVALID,
705 "Illegal member in Composite Field" );
706 }
707
708 return (Object) out;
709
710 error:
711 ERROR_SECTION;
712 return ERROR;
713 }
714
715
_dxf_FlattenHierarchy(Object in)716 Object _dxf_FlattenHierarchy ( Object in )
717 {
718 CompositeField out = NULL;
719
720 int position = 0;
721
722
723 if ( DXGetObjectClass ( in ) == CLASS_FIELD )
724 return in;
725 else
726 {
727 if ( ( NULL == ( out = DXNewCompositeField () ) )
728 ||
729 !_flatten_hierarchy ( in, out, &position ) )
730 goto error;
731
732 DXDelete ( (Object) in ); in = NULL;
733
734 return (Object) out;
735 }
736
737 error:
738 ERROR_SECTION;
739
740 DXDelete ( (Object) out );
741 DXDelete ( (Object) in );
742
743 return ERROR;
744 }
745
746
747 #if 0
748 /* XXX - Next two are unused */
749
750 /*
751 * What we have to work with:
752 *
753 * Object DXGetMember (Group g, char *name);
754 * Object DXGetEnumeratedMember (Group g, int n, char **name);
755 * Object DXGetSeriesMember (Series s, int n, float *position);
756 *
757 * Series DXSetSeriesMember (Series s, int n, double position, Object o);
758 * Group DXSetMember (Group g, char *name, Object value);
759 * Group DXSetEnumeratedMember (Group g, int n, Object value);
760 *
761 * member attribute when a Group when a Series
762 * ---------------- ------------ -------------
763 * member name Use Ignore
764 * position number Ignore Use
765 * position floating point value Ignore Use
766 */
767
768 Group _dxf_SetMember_G_S ( Group g, int n, char *name, float position, Object o )
769 {
770 DXASSERT ( DXGetObjectClass ( (Object)g ) == CLASS_GROUP );
771 DXASSERT ( o );
772
773 if ( DXGetGroupClass(g) == CLASS_SERIES )
774 {
775 if ( name && DXQueryDebug ( "P" ) )
776 DXWarning ( "Series group member name (%s) ignored.", name );
777
778 return (Group) DXSetSeriesMember ( (Series)g, n, position, o );
779 }
780 else
781 return DXSetMember ( g, name, o );
782 }
783
784
785 Object _dxf_GetEnumeratedMember_G_S ( Group g, int n, char **name, float *position )
786 {
787 DXASSERT ( DXGetObjectClass((Object)g)==CLASS_GROUP );
788 DXASSERT ( name );
789 DXASSERT ( position );
790
791
792 if ( DXGetGroupClass(g) == CLASS_SERIES )
793 {
794 *name = NULL; /* should not be used downstream */
795
796 return DXGetSeriesMember ( (Series)g, n, position );
797 }
798 else
799 {
800 *position = 0.0; /* should not be used downstream */
801
802 return DXGetEnumeratedMember ( g, n, name );
803 }
804 }
805 #endif
806
807 /*--------------------------- End Group Access section ----------------------*/
808
809
810 /*----------------------------- Begin Memory section ------------------------*/
811
812
813 /*------------------------------ End Memory section -------------------------*/
814
815
816 /*----------------------------- Begin Generic section -----------------------*/
817
818 /* Extern routine. Consult the file header */
_dxf_greater_prime(int in)819 int _dxf_greater_prime ( int in )
820 {
821 int i, j, k;
822 int prime;
823
824 i = in;
825 prime = FALSE;
826
827 while ( !prime ) {
828 i++;
829 prime = TRUE;
830 k = sqrt ( (float) i ) + 1;
831
832 for ( j=2; j<=k; j++ )
833 if ( ( i % j ) == 0 ) {
834 prime = FALSE;
835 break;
836 }
837 }
838 return ( i );
839 }
840
841 /*------------------------------ End Generic section ------------------------*/
842
843 /*---------------------- Begin filename construction section ----------------*/
844
845
846 /*-------------------*/
847
848
849 /*----------------------- Begin Field manipulation section ------------------*/
850
_dxf_MakeFieldEmpty(Field field)851 Field _dxf_MakeFieldEmpty ( Field field )
852 {
853 char *name;
854 int protect = 0;
855
856 DXASSERT ( field != NULL );
857 DXASSERT ( DXGetObjectClass ( (Object) field ) == CLASS_FIELD );
858
859 while ( DXGetEnumeratedComponentValue ( field, 0, &name ) )
860 {
861 if ( protect++ > 512 )
862 DXErrorGoto
863 ( ERROR_UNEXPECTED,
864 "unusually large number of components, _dxf_MakeFieldEmpty" );
865
866 if ( !DXDeleteComponent ( field, name )
867 ||
868 ( DXGetError() != ERROR_NONE ) )
869 goto error;
870 }
871
872 if ( DXGetError() != ERROR_NONE ) goto error;
873
874 return field;
875
876 error:
877 ERROR_SECTION;
878 return ERROR;
879 }
880
881
882 /*
883 * for 'infield', calculate and set a "fuzz" component.
884 * 'type' values progress as follows:
885 * 0 for surfaces and volumes
886 * 1 for line connections
887 * 2 for positions
888 */
889 /* Extern routine. Consult the file header */
_dxf_SetFuzzAttribute(Field infield,int type)890 Field _dxf_SetFuzzAttribute ( Field infield, int type )
891 {
892 Array positions;
893 int ndim;
894 int npoints;
895 double fuzz;
896
897 if ( !DXEmptyField ( infield )
898 && DXExists ( (Object) infield, "positions" )
899 && ( positions = (Array) DXGetComponentValue ( infield, "positions" ) )
900 && DXGetArrayInfo ( positions, &npoints, NULL, NULL, NULL, &ndim )
901 && ( npoints > 0 ) )
902 {
903
904 #if 0
905
906 if ( ( ndim != 2 ) && ( ndim != 3 ) )
907 {
908 DXSetError
909 ( ERROR_NOT_IMPLEMENTED,
910 "\"positions\" dimensionality %d not in (2..3)",
911 ndim );
912 goto error;
913 }
914
915 if ( !DXBoundingBox ( (Object) infield, bbox ) )
916 goto error;
917
918 for ( i = 1, min = bbox[0], max = bbox[0]; i < 8; i++ )
919 {
920 if ( bbox[i].x < min.x ) min.x = bbox[i].x;
921 if ( bbox[i].y < min.y ) min.y = bbox[i].y;
922 if ( bbox[i].z < min.z ) min.z = bbox[i].z;
923 if ( bbox[i].x > max.x ) max.x = bbox[i].x;
924 if ( bbox[i].y > max.y ) max.y = bbox[i].y;
925 if ( bbox[i].z > max.z ) max.z = bbox[i].z;
926 }
927 /*
928 * Temporarily use vector 'min' to hold 'max' - 'min'
929 */
930 min.x = ( max.x - min.x );
931 min.y = ( max.y - min.y );
932 min.z = ( max.z - min.z );
933
934 fuzz = sqrt ( ( min.x * min.x ) +
935 ( min.y * min.y ) +
936 ( min.z * min.z ) );
937
938 if ( ( type < 1 ) || ( type > 2 ) )
939 {
940 DXWarning
941 ( "_dxf_SetFuzzAttribute ( type = %d ) mis-specified, using type=2",
942 type );
943 type = 2;
944 }
945
946 /*
947 * Fuzz value had to be chosen by trial and error
948 * image resolution ~= 500; object size ~= 10.0
949 */
950
951 fuzz = fuzz / 200.0;
952 fuzz = fuzz * ( (double) type );
953
954 #else
955
956 fuzz = 2.0 * type;
957
958 #endif
959
960 if ( !DXSetFloatAttribute ( (Object) infield, "fuzz", fuzz ) )
961 goto error;
962
963 return infield;
964 }
965
966 else if ( DXGetError() == ERROR_NONE )
967 return infield;
968
969 else
970 return ERROR;
971
972 error:
973 ERROR_SECTION;
974 return ERROR;
975 }
976
977
978 /*
979 *
980 */
981 Field
_dxf_SetDefaultColor(Field input,RGBColor color)982 _dxf_SetDefaultColor ( Field input, RGBColor color )
983 {
984 int np;
985 Array p;
986 Array carray = NULL;
987 int set_default = 1;
988 int i;
989
990 static char *color_names[] = { "colors", "front colors", NULL };
991
992 for ( i=0; color_names[i] != NULL; i++ )
993 if ( DXGetComponentValue ( input, color_names[i] ) )
994 set_default = 0;
995
996 if ( set_default && !DXEmptyField ( input ) )
997 {
998 if ( ERROR == ( p = (Array) DXGetComponentValue
999 ( input, "positions" ) ) )
1000 DXErrorGoto
1001 ( ERROR_ASSERTION,
1002 "A non-EmptyField has no positions" );
1003
1004 if ( !DXGetArrayInfo ( p, &np, NULL, NULL, NULL, NULL )
1005 ||
1006 ( ERROR == ( carray = (Array) DXNewConstantArray
1007 ( np,
1008 (Pointer) &color,
1009 TYPE_FLOAT, CATEGORY_REAL,
1010 1, 3 ) ) )
1011 ||
1012 !DXSetComponentValue ( input, "colors", (Object) carray ) )
1013 goto error;
1014
1015 carray = NULL;
1016
1017 if ( !DXSetComponentAttribute
1018 ( input, "colors", "dep",
1019 (Object) DXNewString ( "positions" ) ) )
1020 goto error;
1021 }
1022
1023 return input;
1024
1025 error:
1026 ERROR_SECTION;
1027
1028 DXDelete ( (Object) carray ); carray = NULL;
1029
1030 return ERROR;
1031 }
1032
1033 /*------------------------ End Field manipulation section -------------------*/
1034
1035 /*------------------------------ Begin Image section ------------------------*/
1036
1037 #define SMALL 0.4
1038 #define NONZERO(a) ( ( (a) < -SMALL ) || ( (a) > SMALL ) )
1039 #define ZERO(a) ( ( (a) >= -SMALL ) && ( (a) <= SMALL ) )
1040
1041 /*-------------------*/
1042
1043
1044 /*-------------------*/
1045
1046 Field
_dxf_GetEnumeratedImage(Object o,int n)1047 _dxf_GetEnumeratedImage ( Object o, int n )
1048 {
1049 int i;
1050 Field image = NULL;
1051 Class class;
1052 float position;
1053
1054 if ( ( class = DXGetObjectClass ( o ) ) == CLASS_FIELD )
1055 {
1056 if ( n == 0 )
1057 return ( (Field) o );
1058 else
1059 DXErrorGoto ( ERROR_ASSERTION, "_dxf_GetEnumeratedImage(Field,n!=0)" )
1060 }
1061 else if ( ( class == CLASS_GROUP )
1062 &&
1063 ( ( class = DXGetGroupClass ( (Group) o ) ) == CLASS_SERIES ) )
1064 {
1065 for ( i=0;
1066 ( image = (Field) DXGetSeriesMember ( (Series) o, i, &position ) );
1067 i++ )
1068 if ( ( (int)position ) == n ) {
1069 if ( _dxf_ValidImageField ( image ) )
1070 return image;
1071 else
1072 goto error;
1073 }
1074 }
1075 else if ( DXGetError() != ERROR_NONE )
1076 goto error;
1077 else
1078 DXErrorGoto ( ERROR_INTERNAL, "Illegal object type" )
1079
1080 return NULL;
1081
1082 error:
1083 ERROR_SECTION;
1084 return ERROR;
1085 }
1086
1087
1088 /*-------------------*/
1089
1090
1091 SizeData *
_dxf_GetImageAttributes(Object o,SizeData * sd)1092 _dxf_GetImageAttributes ( Object o, SizeData *sd )
1093 {
1094 int i;
1095 Field image = NULL;
1096 Class class;
1097 float position;
1098 int w, h;
1099
1100 sd->height = VALUE_UNSPECIFIED;
1101 sd->width = VALUE_UNSPECIFIED;
1102 sd->startframe = VALUE_UNSPECIFIED;
1103 sd->endframe = VALUE_UNSPECIFIED;
1104
1105 if ( ( class = DXGetObjectClass ( o ) ) == CLASS_FIELD )
1106 {
1107 if ( !DXGetImageSize ( (Field) o, &sd->width, &sd->height ) )
1108 goto error;
1109
1110 sd->startframe = 0;
1111 sd->endframe = 0;
1112 }
1113 else if ( ( class == CLASS_GROUP )
1114 &&
1115 ( ( class = DXGetGroupClass ( (Group) o ) ) == CLASS_SERIES ) )
1116
1117 for ( i=0;
1118 ( image = (Field) DXGetSeriesMember ( (Series) o, i, &position ) );
1119 i++ )
1120 {
1121 /*
1122 * XXX - position values are ignored.
1123 */
1124 if ( !DXGetImageSize ( image, &w, &h ) ) goto error;
1125
1126 sd->endframe = i;
1127
1128 if ( i == 0 )
1129 {
1130 sd->height = h;
1131 sd->width = w;
1132 sd->startframe = 0;
1133 }
1134 else if ( ( sd->height != h ) || ( sd->width != w ) )
1135 DXErrorGoto
1136 ( ERROR_DATA_INVALID,
1137 "Image Series changes sizes internally" );
1138 }
1139
1140 else if ( DXGetError() == ERROR_NONE )
1141 DXErrorGoto ( ERROR_INTERNAL, "Illegal object type" )
1142 else
1143 goto error;
1144
1145 return sd;
1146
1147 error:
1148 ERROR_SECTION;
1149 return ERROR;
1150 }
1151
1152
1153 /*-------------------*/
1154
1155 /* Extern routine. Consult the file header */
_dxf_ValidImageField(Field image)1156 Error _dxf_ValidImageField ( Field image )
1157 {
1158 int h, w;
1159
1160 if ( !DXGetImageSize ( image, &w, &h ) )
1161 {
1162 DXResetError();
1163 return ERROR;
1164 }
1165 else
1166 return OK;
1167 }
1168
1169
1170 /* Extern routine. Consult the file header */
_dxf_CheckImage(Field image)1171 Field _dxf_CheckImage ( Field image )
1172 {
1173 int width, height;
1174 int test_height, test_width;
1175 int count[2];
1176 float Origin[2];
1177 float Delta[4];
1178
1179 /* Do We Really know what is assumed? Find out. */
1180
1181 if ( !DXGetImageSize ( image, &width, &height ) )
1182 goto error;
1183
1184 if ( !_dxf_GetComponentData ( (Object)image,
1185 POSITIONS_2D_COMP,
1186 count, (Pointer)Origin, (Pointer)Delta,
1187 NULL ) )
1188 goto error;
1189
1190 if ( NONZERO ( Delta[0] ) || ZERO ( Delta[1] ) ||
1191 ZERO ( Delta[2] ) || NONZERO ( Delta[3] ) ||
1192 ( count[0] == 0 ) || ( count[1] == 0 ) )
1193 DXWarning ( "Image has unsupportable size attributes." );
1194
1195 test_width = ( Delta[0] * count[0] ) + ( Delta[2] * count[1] );
1196 test_height = ( Delta[1] * count[0] ) + ( Delta[3] * count[1] );
1197
1198 if ( ( test_height != height ) || ( test_width != width ) )
1199 DXWarning ( "DXGetImageSize data does not match DXQueryGridPositions" );
1200
1201 return image;
1202
1203 error:
1204 ERROR_SECTION;
1205 return ERROR;
1206 }
1207
1208
_dxf_CountImages(Object image,int * count)1209 Error _dxf_CountImages ( Object image, int *count )
1210 {
1211 int i;
1212 Object member;
1213
1214 DXASSERTGOTO ( image && count );
1215
1216 switch ( DXGetObjectClass ( image ) )
1217 {
1218 case CLASS_FIELD:
1219 (*count)++;
1220 break;
1221
1222 case CLASS_GROUP:
1223 if ( DXGetGroupClass ( (Group) image ) == CLASS_COMPOSITEFIELD )
1224 (*count)++;
1225 else
1226 {
1227 for ( i = 0;
1228 (member=DXGetEnumeratedMember ( (Group)image, i, NULL ));
1229 i++ )
1230 if ( !_dxf_CountImages ( member, count ) )
1231 goto error;
1232 }
1233 break;
1234
1235 default:
1236 DXErrorGoto ( ERROR_DATA_INVALID, "Image is not a group or field" );
1237 }
1238
1239 return OK;
1240
1241 error:
1242 ERROR_SECTION;
1243 return ERROR;
1244 }
1245
1246
1247
1248 static
_get_image_deltas(Object image,float * deltas,int * set)1249 Error _get_image_deltas ( Object image, float *deltas, int *set )
1250 {
1251
1252 DXASSERTGOTO ( image && deltas && set );
1253
1254 switch ( DXGetObjectClass ( image ) )
1255 {
1256 case CLASS_FIELD:
1257 {
1258 float Origin[2];
1259 float Delta[4];
1260 int count[2];
1261 Pointer ptr;
1262
1263 if ( !_dxf_GetComponentData ( (Object)image,
1264 POSITIONS_2D_COMP,
1265 count, (Pointer)Origin, (Pointer)Delta,
1266 &ptr ) )
1267 goto error;
1268
1269 if ( ptr )
1270 DXErrorGoto2
1271 ( ERROR_DATA_INVALID,
1272 "#10612", /* only regular positions for %s supported */
1273 "images" )
1274
1275 /* Direction is a consideration Only. Not the magnitude. */
1276
1277 Delta[0] = ( Delta[0] == 0.0 ) ? 0 : ( Delta[0] > 0.0 ) ? 1 : -1;
1278 Delta[1] = ( Delta[1] == 0.0 ) ? 0 : ( Delta[1] > 0.0 ) ? 1 : -1;
1279 Delta[2] = ( Delta[2] == 0.0 ) ? 0 : ( Delta[2] > 0.0 ) ? 1 : -1;
1280 Delta[3] = ( Delta[3] == 0.0 ) ? 0 : ( Delta[3] > 0.0 ) ? 1 : -1;
1281
1282 if ( *set )
1283 {
1284 if ( 0 != memcmp
1285 ( (char *)deltas, (char *)Delta, sizeof(Delta) ) )
1286 DXErrorGoto
1287 ( ERROR_DATA_INVALID,
1288 "images must have like positional deltas" );
1289 }
1290 else
1291 {
1292 if ( !memcpy ( (char *)deltas, (char *)Delta, sizeof(Delta) ) )
1293 DXErrorGoto
1294 ( ERROR_INTERNAL, "memcpy()" );
1295
1296 *set = 1;
1297 }
1298 }
1299 break;
1300
1301 case CLASS_GROUP:
1302 {
1303 int i;
1304 Object member;
1305 #if 0
1306 if ( DXGetGroupClass ( (Group) in ) != CLASS_COMPOSITEFIELD )
1307 DXErrorGoto
1308 ( ERROR_DATA_INVALID, "Illegal member in Composite Field" );
1309 #endif
1310 for ( i = 0;
1311 (member=DXGetEnumeratedMember ( (Group)image, i, NULL ));
1312 i++ )
1313 if ( !_get_image_deltas ( member, deltas, set ) )
1314 goto error;
1315 }
1316 break;
1317
1318 default:
1319 DXErrorGoto ( ERROR_DATA_INVALID,
1320 "Illegal member in Composite Field" );
1321 }
1322
1323 return OK;
1324
1325 error:
1326 ERROR_SECTION;
1327 return ERROR;
1328 }
1329
1330
_dxf_GetImageDeltas(Object image,float * deltas)1331 Error _dxf_GetImageDeltas ( Object image, float *deltas )
1332 {
1333 int set = 0;
1334
1335 DXASSERTGOTO ( image && deltas );
1336
1337 /* Get AND Verify they match */
1338
1339 if ( !_get_image_deltas ( image, deltas, &set ) )
1340 goto error;
1341
1342 if ( set == 0 )
1343 DXErrorGoto ( ERROR_INTERNAL, "_dxf_GetImageDeltas. set == 0" );
1344
1345 return OK;
1346
1347 error:
1348 ERROR_SECTION;
1349 return ERROR;
1350 }
1351
1352
_dxf_CheckImageDeltas(Object image,int * transposed)1353 Error _dxf_CheckImageDeltas ( Object image, int *transposed )
1354 {
1355 float deltas[4];
1356 int dsignature = 0;
1357
1358 DXASSERTGOTO ( transposed != NULL );
1359
1360 if ( !_dxf_GetImageDeltas ( image, deltas ) )
1361 goto error;
1362
1363 /*
1364 * delta characterization:
1365 * for each term: d[0] d[1] d[2] d[3]
1366 * assign bits for +,-: 0 1 | 2 3 | 4 5 | 6 7
1367 * with the values: 1 .. 128
1368 */
1369 dsignature |= (deltas[0]==0)? 0 : (deltas[0]>0)? 1 : 2;
1370 dsignature |= (deltas[1]==0)? 0 : (deltas[1]>0)? 4 : 8;
1371 dsignature |= (deltas[2]==0)? 0 : (deltas[2]>0)? 16 : 32;
1372 dsignature |= (deltas[3]==0)? 0 : (deltas[3]>0)? 64 : 128;
1373
1374 if ( dsignature == ( 16 | 4 ) ) /* y:first, x:fastest */
1375 *transposed = 0;
1376
1377 else if ( dsignature == ( 1 | 64 ) ) /* x:first, y:fastest */
1378 *transposed = 1;
1379
1380 else
1381 DXErrorGoto
1382 ( ERROR_DATA_INVALID, "image has unsupported deltas" );
1383
1384 return OK;
1385
1386 error:
1387 ERROR_SECTION;
1388 return ERROR;
1389 }
1390
1391
1392 #if 0
1393 #endif
1394 /* Extern routine. Consult the file header */
_dxf_GetImageOrigin(Field image,int * xorigin,int * yorigin)1395 Error _dxf_GetImageOrigin ( Field image, int *xorigin, int *yorigin )
1396 {
1397 int count[2];
1398 int offsets[2];
1399 Pointer ptr;
1400
1401 if ( !_dxf_GetComponentData ( (Object)image,
1402 QUAD_CONNECTIONS_COMP,
1403 count, (Pointer)offsets, NULL, &ptr ) )
1404 goto error;
1405 #if 0
1406 _dxf_GetComponentData ( (Object)image,
1407 POSITIONS_2D_COMP,
1408 count, (Pointer)Origin, (Pointer)Delta, &ptr );
1409 #endif
1410
1411 if ( ptr == NULL )
1412 {
1413 if ( yorigin ) *yorigin = offsets[0];
1414 if ( xorigin ) *xorigin = offsets[1];
1415 #if 0
1416 if ( NULL == ( array = (Array) DXGetComponentValue
1417 ( image, "connections" ) ) )
1418 ErrorGotoPlus2
1419 ( ERROR_MISSING_DATA, "#10250", "image", "\"connections\"" )
1420
1421 if ( DXGetMeshOffsets ( (MeshArray) array, count ) )
1422 {
1423 if ( xorigin ) *xorigin = count[1];
1424 if ( yorigin ) *yorigin = count[0];
1425 }
1426 else
1427 {
1428 if ( DXGetError() != ERROR_NONE ) goto error;
1429
1430 if ( xorigin ) *xorigin = 0;
1431 if ( yorigin ) *yorigin = 0;
1432 }
1433 if ( !CheckImagePosition ( image ) ) goto error;
1434 #endif
1435 }
1436 else
1437 DXErrorGoto2
1438 ( ERROR_DATA_INVALID,
1439 "#10610", /* only regular connections for %s supported */
1440 "images" )
1441
1442 DXDebug ( "A",
1443 "_dxf_GetImageOrigin ( [%x], (=%d), (=%d) )", image, *xorigin, *yorigin );
1444
1445 return OK;
1446
1447 error:
1448 ERROR_SECTION;
1449 return ERROR;
1450 }
1451
1452
1453 /* Extern routine. Consult the file header */
_dxf_SetImageOrigin(Field image,int xorigin,int yorigin)1454 Field _dxf_SetImageOrigin ( Field image, int xorigin, int yorigin )
1455 {
1456 int count[2];
1457 int offsets[2];
1458 float Origin[2];
1459 float Delta[4];
1460 Pointer ptr;
1461 Array array;
1462
1463 if ( !_dxf_GetComponentData ( (Object)image,
1464 POSITIONS_2D_COMP,
1465 count, (Pointer)Origin, (Pointer)Delta,
1466 &ptr ) )
1467 goto error;
1468
1469 if ( ptr )
1470 DXErrorGoto2
1471 ( ERROR_DATA_INVALID,
1472 "#10612", /* only regular positions for %s supported */
1473 "images" )
1474
1475 if ( !_dxf_GetComponentData ( (Object)image,
1476 QUAD_CONNECTIONS_COMP,
1477 count, (Pointer)offsets, NULL, &ptr ) )
1478 goto error;
1479
1480 if ( ptr == NULL )
1481 {
1482 if ( Delta[1] /*U.y*/ != 0.0 )
1483 {
1484 /* x varying fastest (y slowest) */
1485
1486 offsets[0] = yorigin;
1487 offsets[1] = xorigin;
1488
1489 Origin[0] = xorigin * Delta[2]; /* V.x */
1490 Origin[1] = yorigin * Delta[1]; /* U.y */
1491 }
1492 else
1493 {
1494 /* y varying fastest */
1495
1496 offsets[0] = xorigin;
1497 offsets[1] = yorigin;
1498
1499 Origin[0] = xorigin * Delta[0]; /* U.x */
1500 Origin[1] = yorigin * Delta[3]; /* V.y */
1501 }
1502
1503 DXDebug ( "A",
1504 "_dxf_SetImageOrigin ( [%x], %d, %d )",
1505 image, xorigin, yorigin );
1506
1507 if ( ( NULL == ( array = _dxf_NewComponentArray
1508 ( QUAD_CONNECTIONS_COMP,
1509 count, (Pointer)offsets, NULL ) ) )
1510 ||
1511 !DXSetComponentValue ( image, "connections", (Object)array )
1512 ||
1513 ( NULL == ( array = _dxf_NewComponentArray
1514 ( POSITIONS_2D_COMP,
1515 count,
1516 (Pointer)Origin, (Pointer)Delta ) ) )
1517 ||
1518 !DXSetComponentValue ( image, "positions", (Object)array )
1519 ||
1520 !DXChangedComponentValues ( image, "positions" )
1521 ||
1522 !DXEndField ( image ) )
1523 goto error;
1524 #if 0
1525 if ( !CheckImagePosition ( image ) ) goto error;
1526 #endif
1527 return image;
1528 }
1529 else
1530 DXErrorGoto2
1531 ( ERROR_DATA_INVALID,
1532 "#10610", /* only regular connections for %s supported */
1533 "images" )
1534 error:
1535 ERROR_SECTION;
1536 return ERROR;
1537 }
1538
1539
1540 /* Extern routine. Consult the file header */
_dxf_SetCompositeImageOrigin(CompositeField image,int xorigin,int yorigin)1541 CompositeField _dxf_SetCompositeImageOrigin ( CompositeField image,
1542 int xorigin, int yorigin )
1543 {
1544 Object member;
1545 int cfield_origin[2];
1546 int member_origin[2];
1547 int i;
1548
1549 if ( !DXGetImageBounds ( (Object)image, &cfield_origin[0], &cfield_origin[1],
1550 NULL, NULL ) )
1551 goto error;
1552
1553 if ( ( cfield_origin[0] == xorigin )
1554 &&
1555 ( cfield_origin[1] == yorigin ) )
1556
1557 return image; /* We are in luck */
1558
1559 for ( i = 0;
1560 (member= DXGetEnumeratedMember ( (Group)image, i, NULL ));
1561 i++ )
1562
1563 switch ( DXGetObjectClass ( member ) )
1564 {
1565 case CLASS_FIELD:
1566 if ( !DXGetImageBounds
1567 ( (Object)member,
1568 &member_origin[0], &member_origin[1], NULL, NULL ) )
1569 goto error;
1570
1571 member_origin[0] = ( member_origin[0] - cfield_origin[0] )
1572 + xorigin;
1573 member_origin[1] = ( member_origin[1] - cfield_origin[1] )
1574 + yorigin;
1575
1576 if ( !_dxf_SetImageOrigin
1577 ( (Field)member,
1578 member_origin[0],
1579 member_origin[1] ) )
1580 goto error;
1581
1582 break;
1583
1584 case CLASS_GROUP:
1585
1586 switch ( DXGetGroupClass ( (Group)member ) )
1587 {
1588 case CLASS_COMPOSITEFIELD:
1589
1590 if ( !DXGetImageBounds
1591 ( (Object)member,
1592 &member_origin[0], &member_origin[1],
1593 NULL, NULL ) )
1594 goto error;
1595
1596 member_origin[0]
1597 = ( member_origin[0] - cfield_origin[0] ) + xorigin;
1598
1599 member_origin[1]
1600 = ( member_origin[1] - cfield_origin[1] ) + yorigin;
1601
1602 if ( !_dxf_SetCompositeImageOrigin
1603 ( (CompositeField)member,
1604 member_origin[0],
1605 member_origin[1] ) )
1606 goto error;
1607
1608 break;
1609
1610 default:
1611 DXErrorGoto
1612 ( ERROR_DATA_INVALID,
1613 "Illegal member in Arranged Group" );
1614 }
1615 break;
1616
1617 default:
1618 DXErrorGoto ( ERROR_DATA_INVALID,
1619 "Illegal member in Arranged Group" );
1620 }
1621
1622 return image;
1623 error:
1624 ERROR_SECTION;
1625 return ERROR;
1626
1627 }
1628
1629
1630 #if 0
1631 /* Extents are in x and y, and are normalized min_(x,y) = 0 in special cases.
1632 * For Members in a 'Plain' Group, normalize first, then accumulate.
1633 * For Members in a Composite Field, do not normalize, just accumulate.
1634 * This reinforces the rule that Composite Field members are Non-Overlapping.
1635 */
1636 /* Extern routine. Consult the file header */
1637 Error _dxf_QueryImageExtents ( Object inp, int *min_x, int *min_y,
1638 int *max_x, int *max_y )
1639 {
1640 Class class;
1641 Object inp_member;
1642 int loc_min_x;
1643 int loc_min_y;
1644 int loc_max_x;
1645 int loc_max_y;
1646 int origin[2];
1647 int size[2];
1648 int i;
1649
1650 switch ( class = DXGetObjectClass ( inp ) )
1651 {
1652 case CLASS_GROUP:
1653 switch ( class = DXGetGroupClass ( (Group)inp ) )
1654 {
1655
1656 /* GROUP: extents = sum of normalized extents*/
1657 case CLASS_SERIES:
1658 case CLASS_GROUP:
1659
1660 *min_x = 0;
1661 *min_y = 0;
1662 *max_x = 0;
1663 *max_y = 0;
1664 for ( i=0;
1665 inp_member = DXGetEnumeratedMember
1666 ( (Group)inp, i, NULL );
1667 i++ )
1668 if ( !_dxf_QueryImageExtents
1669 ( inp_member, &loc_min_x, &loc_min_y,
1670 &loc_max_x, &loc_max_y ) )
1671 goto error;
1672 else
1673 {
1674 loc_max_x = loc_max_x - loc_min_x;
1675 loc_max_y = loc_max_y - loc_min_y;
1676 if ( i == 0 )
1677 {
1678 *max_x = loc_max_x;
1679 *max_y = loc_max_y;
1680 }
1681 else
1682 {
1683 *max_x = MAX ( *max_x, loc_max_x );
1684 *max_y = MAX ( *max_y, loc_max_y );
1685 }
1686 }
1687 return OK;
1688
1689 /* COMPOSITE FIELD: extents = sum of extents (unnormalized)*/
1690 case CLASS_COMPOSITEFIELD:
1691
1692 /* XXX - Possible to have valid empty composite field */
1693 *min_x = 0;
1694 *min_y = 0;
1695 *max_x = 0;
1696 *max_y = 0;
1697
1698 for ( i=0;
1699 inp_member = DXGetEnumeratedMember
1700 ( (Group)inp, i, NULL );
1701 i++ )
1702 if ( !_dxf_QueryImageExtents
1703 ( inp_member, &loc_min_x, &loc_min_y,
1704 &loc_max_x, &loc_max_y ) )
1705 goto error;
1706 else
1707 if ( i == 0 )
1708 {
1709 /* Not empty so override defaults */
1710 *min_x = loc_min_x;
1711 *min_y = loc_min_y;
1712 *max_x = loc_max_x;
1713 *max_y = loc_max_y;
1714 }
1715 else
1716 {
1717 *min_x = MIN ( *min_x, loc_min_x );
1718 *min_y = MIN ( *min_y, loc_min_y );
1719 *max_x = MAX ( *max_x, loc_max_x );
1720 *max_y = MAX ( *max_y, loc_max_y );
1721 }
1722 return OK;
1723 break;
1724
1725 default:
1726 ErrorGotoPlus1 ( ERROR_DATA_INVALID, "#10190", "image" );
1727 }
1728 break;
1729
1730 case CLASS_FIELD:
1731
1732 if ( !_dxf_GetImageOrigin ( (Field)inp, &origin[0], &origin[1] )
1733 ||
1734 !DXGetImageSize ( (Field)inp, &size[0], &size[1] ) )
1735 goto error;
1736
1737 *min_x = origin[0];
1738 *min_y = origin[1];
1739 *max_x = origin[0] + size[0];
1740 *max_y = origin[1] + size[1];
1741 return OK;
1742
1743 default:
1744 ErrorGotoPlus1 ( ERROR_DATA_INVALID, "#10190", "image" );
1745
1746 }
1747 error:
1748 ERROR_SECTION;
1749 return ERROR;
1750 }
1751 #endif
1752
1753 #define CLAMP(s, d) \
1754 { \
1755 float t = s; \
1756 d = (t <= 0.0) ? 0 : (t >= 1.0) ? 255 : 255*t; \
1757 }
1758
1759 #define COPY_FLOAT_INTO_UBYTE \
1760 { \
1761 float *src = (float *)srcPtr; \
1762 ubyte *dst = (ubyte *)dstPtr; \
1763 \
1764 for ( y=0, is=0, id=(((sy0*wd)+sx0)*3); y<hs; y++, id+=(wd-ws)*3) \
1765 for ( x=0; x<3*ws; x++) \
1766 CLAMP(src[is++], dst[id++]); \
1767 }
1768
1769 #define COPY_UBYTE_INTO_FLOAT \
1770 { \
1771 ubyte *src = (ubyte *)srcPtr; \
1772 float *dst = (float *)dstPtr; \
1773 float d = 1.0 / 255.0; \
1774 \
1775 for ( y=0, is=0, id=(((sy0*wd)+sx0)*3); y<hs; y++, id+=(wd-ws)*3) \
1776 for ( x=0; x<3*ws; x++) \
1777 dst[id++] = d*src[is++]; \
1778 }
1779
1780 #define COPY_SAME_INTO_SAME(type) \
1781 { \
1782 type *src = (type *)srcPtr; \
1783 type *dst = (type *)dstPtr; \
1784 \
1785 for ( y=0, is=0, id=(((sy0*wd)+sx0)*3); y<hs; y++, id+=(wd-ws)*3) \
1786 for ( x=0; x<3*ws; x++) \
1787 dst[id++] = src[is++]; \
1788 }
1789
1790 #define COPY_MAPPED_INTO_FLOAT \
1791 { \
1792 ubyte *src = (ubyte *)srcPtr; \
1793 float *dst = (float *)dstPtr; \
1794 \
1795 for ( y=0, is=0, id=((sy0*wd)+sx0)*3; y<hs; y++, id+=(wd-ws)*3) \
1796 for ( x=0; x<ws; x++) \
1797 { \
1798 float *m = srcMap + 3*src[is++]; \
1799 dst[id++] = *m++; \
1800 dst[id++] = *m++; \
1801 dst[id++] = *m++; \
1802 } \
1803 }
1804
1805 #define COPY_MAPPED_INTO_UBYTE \
1806 { \
1807 ubyte *src = (ubyte *)srcPtr; \
1808 ubyte *dst = (ubyte *)dstPtr; \
1809 \
1810 for ( y=0, is=0, id=((sy0*wd)+sx0)*3; y<hs; y++, id+=(wd-ws)*3) \
1811 for ( x=0; x<ws; x++) \
1812 { \
1813 float *m = srcMap + src[is++]; \
1814 CLAMP(*m++, dst[id++]); \
1815 CLAMP(*m++, dst[id++]); \
1816 CLAMP(*m++, dst[id++]); \
1817 } \
1818 }
1819
1820 static
1821 /*
1822 * Place 'source' at location ('xoff','yoff') within 'destination'.
1823 */
PlaceCompositeMember(Object source,int xoff,int yoff,Field destination)1824 Field PlaceCompositeMember ( Object source,
1825 int xoff, int yoff, Field destination )
1826 {
1827 Object member;
1828 int i, x, y;
1829 int sx0, sy0, sx1, sy1, is, hs, ws;
1830 int dx0, dy0, dx1, dy1, id, hd, wd;
1831 Array array;
1832 Pointer srcPtr, dstPtr;
1833 Type src_type, dst_type, map_type;
1834 int src_vector;
1835 int rank, shape[32];
1836 float *srcMap = NULL;
1837
1838 switch ( DXGetObjectClass ( source ) )
1839 {
1840 case CLASS_GROUP:
1841 switch ( DXGetGroupClass ( (Group)source ) )
1842 {
1843 case CLASS_COMPOSITEFIELD:
1844 for ( i=0;
1845 (member=DXGetEnumeratedMember
1846 ( (Group)source, i, NULL ));
1847 i++ )
1848 if ( !PlaceCompositeMember
1849 ( member, xoff, yoff, destination ) )
1850 goto error;
1851
1852 return destination;
1853 break;
1854
1855 default:
1856 DXErrorGoto ( ERROR_DATA_INVALID, "Illegal object type" );
1857 }
1858 break;
1859
1860 case CLASS_FIELD:
1861
1862 if ( !DXGetImageBounds ( source, &sx0, &sy0, &sx1, &sy1 ) )
1863 goto error;
1864
1865 sx1 += sx0;
1866 sy1 += sy0;
1867
1868 sx0 = sx0 + xoff;
1869 sy0 = sy0 + yoff;
1870 sx1 = sx1 + xoff;
1871 sy1 = sy1 + yoff;
1872
1873 if ( !DXGetImageBounds
1874 ( (Object)destination, &dx0, &dy0, &dx1, &dy1 ) )
1875 goto error;
1876
1877 dx1 += dx0;
1878 dy1 += dy0;
1879
1880 /* width and height of source and destination */
1881 ws = sx1 - sx0;
1882 hs = sy1 - sy0;
1883 wd = dx1 - dx0;
1884 hd = dy1 - dy0;
1885
1886 if ( ( sx0 < 0 ) || ( sx0 > wd ) || ( sx1 < 0 ) || ( sx1 > wd )
1887 ||
1888 ( sy0 < 0 ) || ( sy0 > hd ) || ( sy1 < 0 ) || ( sy1 > hd )
1889 ||
1890 ( ws > wd ) || ( hs > hd ) )
1891 DXErrorGoto ( ERROR_DATA_INVALID, "Image sizes clash" );
1892
1893 /* XXX - Valid only for X varying fastest */
1894
1895 array = (Array)DXGetComponentValue((Field)source, "colors");
1896 srcPtr = (Pointer)DXGetArrayData(array);
1897
1898 DXGetArrayInfo(array, NULL, &src_type, NULL, &rank, shape);
1899
1900 if (rank == 0 || (rank == 1 && shape[0] == 1))
1901 src_vector = 0;
1902 else if (rank == 1 && shape[0] == 3)
1903 src_vector = 1;
1904 else
1905 DXErrorGoto(ERROR_DATA_INVALID,
1906 "images must be either scalar, 1-vector or 3-vector");
1907
1908 if (! src_vector)
1909 {
1910 if (src_type != TYPE_UBYTE)
1911 {
1912 DXErrorGoto(ERROR_DATA_INVALID,
1913 "Delayed-color image pixels must be ubytes");
1914 }
1915
1916 array = (Array)DXGetComponentValue((Field)source, "color map");
1917 if (! array)
1918 DXErrorGoto(ERROR_DATA_INVALID,
1919 "Delayed-color image has no color map");
1920
1921 DXGetArrayInfo(array, NULL, &map_type, NULL, &rank, shape);
1922
1923 if (map_type != TYPE_FLOAT || rank != 1 || shape[0] != 3)
1924 DXErrorGoto(ERROR_DATA_INVALID,
1925 "Delayed-color color map must be float 3-vector");
1926
1927 srcMap = (float *)DXGetArrayData(array);
1928 }
1929 else
1930 if (src_type != TYPE_UBYTE && src_type != TYPE_FLOAT)
1931 DXErrorGoto(ERROR_DATA_INVALID,
1932 "color image pixels must be ubytes or floats");
1933
1934 array = (Array)DXGetComponentValue(destination, "colors");
1935 dstPtr = (Pointer)DXGetArrayData(array);
1936
1937 DXGetArrayInfo(array, NULL, &dst_type, NULL, &rank, shape);
1938
1939 if (rank != 1 || shape[0] != 3)
1940 DXErrorGoto(ERROR_DATA_INVALID,
1941 "destination image must be 3-vector");
1942
1943 if (src_type != TYPE_UBYTE && src_type != TYPE_FLOAT)
1944 DXErrorGoto(ERROR_DATA_INVALID,
1945 "destination image pixels must be ubytes or floats");
1946
1947 if (src_vector)
1948 {
1949 if (src_type == TYPE_UBYTE && dst_type == TYPE_UBYTE)
1950 COPY_SAME_INTO_SAME(ubyte)
1951 else if (src_type == TYPE_UBYTE && dst_type == TYPE_FLOAT)
1952 COPY_UBYTE_INTO_FLOAT
1953 else if (src_type == TYPE_FLOAT && dst_type == TYPE_UBYTE)
1954 COPY_FLOAT_INTO_UBYTE
1955 else
1956 COPY_SAME_INTO_SAME(float);
1957 }
1958 else
1959 {
1960 if (dst_type == TYPE_FLOAT)
1961 COPY_MAPPED_INTO_FLOAT
1962 else
1963 COPY_MAPPED_INTO_UBYTE;
1964 }
1965
1966 return destination;
1967
1968 break;
1969
1970 default:
1971 DXErrorGoto ( ERROR_DATA_INVALID, "Illegal object type" );
1972 }
1973
1974 error:
1975 ERROR_SECTION;
1976 return ERROR;
1977 }
1978
1979 /* Extern routine. Consult the file header */
_dxf_SimplifyCompositeImage(CompositeField image)1980 Field _dxf_SimplifyCompositeImage ( CompositeField image )
1981 {
1982 int min_x;
1983 int min_y;
1984 int max_x;
1985 int max_y;
1986 Field fld_image = NULL;
1987 Pointer *pixels;
1988 Array array;
1989
1990 if ( !DXGetImageBounds ( (Object) image, &min_x, &min_y, &max_x, &max_y ) )
1991 goto error;
1992
1993 max_x += min_x; /* look below. */
1994 max_y += min_y;
1995
1996 max_x = max_x - min_x;
1997 max_y = max_y - min_y;
1998
1999 fld_image = DXMakeImageFormat(max_x, max_y, "BYTE");
2000 if (! fld_image)
2001 goto error;
2002
2003 array = (Array)DXGetComponentValue(fld_image, "colors");
2004 if (! array)
2005 goto error;
2006
2007 pixels = DXGetArrayData(array);
2008
2009 memset((char *)pixels, 0, (max_x * max_y * DXGetItemSize(array)));
2010
2011 if ( !PlaceCompositeMember((Object)image, -min_x, -min_y, fld_image))
2012 goto error;
2013
2014 return fld_image;
2015
2016 error:
2017
2018 ERROR_SECTION;
2019
2020 DXDelete ( (Object)fld_image);
2021
2022 return ERROR;
2023 }
2024
2025 /*------------------------------- End Image section -------------------------*/
2026