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