Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!apple!well!shf From: shf@well.UUCP (Stuart H. Ferguson) Newsgroups: comp.sys.amiga.tech Subject: Response to DR2D format specification Message-ID: <14491@well.UUCP> Date: 10 Nov 89 06:44:37 GMT Reply-To: shf@well.UUCP (Stuart H. Ferguson) Organization: The Blue Planet Lines: 305 +---- Ross Cunniff (cunniff%hpfcrt@hplabs.HP.COM) writes: | | The following is the format of the DR2D IFF FORM file produced | by ProVector, a 2-dimensional structured graphics program. I see failings with this format in two main areas: 1. Transportability across applications. Some aspects of the format were clearly designed to work well with this one drawing program but will hinder other developers from using it for different applications. Since the main reason for IFF is this tranportability of data, this is a serious consideration in any format that wants to become a "standard." 2. Conformance with IFF philosophy. Although it's never been explicity documented what constitutes a "good" IFF FORM, it is possible to glean some of the basic design notions from studying the IFF documentation, the standard FORM's and the IFF format itself. Being a something of a student of IFF, I think I can illuminate some areas where this proposed format clashes with general IFF principles. Let me first address the transportability and generality issues; those issues that will affect how well this format can adapt to other applications than the one for which it was specifically designed. | Coordinates are specified in IEEE format (see note 1 for a | description of the IEEE format). Storing coordinates in floating point is not an ideal choice. For some things floating point numbers are essential, but not for drawings. The advantage that floating point numbers have over fixed point is that they are valid over a much greater range, and are therefore useful for calculations involving multiplications. Fixed point numbers, however, are more accurate and operations on them are faster, but fixed within a narrow range. This makes them more appropriate for calculations involving additions and subtractions. Since coordinates of greatly differing magnitude cannot be mixed in the same drawing, and the edges of a drawing provide a natural boundary for the scale of the numbers, and the fact that vectors are often added and rarely multiplied, fixed point coordinates (integers) are a more natural choice for drawings. This does not mean that any given program couldn't use floating point numbers internally. It just means that the Interchange format for drawings would use the more natural fixed point notation for exchanging data between varied applications, some which use floating point interanlly and some which do not. But none are required to parse it when they don't have to. For programs which want floating point, the drawing header chunk, | struct DRHDstruct { | LONG ID; | LONG Size; /* Always 18 */ | IEEE p_xmin, p_ymin, /* Minimum and maximum */ | p_xmax, p_ymax; /* coordinates of the drawing area */ | }; could be expanded to include the bounding box of the fixed point coordinates as well as their equivalents in floating point. Thus a floating point program such as ProVector could transform the integer values in the DR2D file into their equivalent floating point values, with no loss of precision, with one floating multiply. Since a drawing requires at least this much calculation each time it's displayed, I can't see how this extra computation would be objectionable. It saves a lot of effort for those who only want to deal with integers. | typedef struct { | UBYTE FillType; /* One of FT_*, above */ | UBYTE FillValue; /* See note 3 */ | UBYTE EdgeType; /* One of ET_*, above */ | UBYTE EdgeValue; /* Edge color index */ | USHORT WhichLayer; /* Which layer it's in */ | IEEE EdgeThick; /* Line width */ | IEEE XMin, YMin, /* Bounding box of obj. */ | XMax, YMax; /* including line width */ | } ObjHdr; /* Size == 26 */ This "Object Header" record comes along with almost all primitive objects in the file. Although most of these parameters are reasonable, I have problems with two of them: WhichLayer and the X/Y-Min/Max bounding box. WhichLayer is somewhat ambigious. Can you have, for example, a group with components in more than one layer? If so, what does it mean? The "use a symbol" chunk has its own WhichLayer field, as do each of the components of the symbol. Which layer wins? I think that the layer information does not belong in the data for each object, but rather as a property of a whole collection of objects. I will spell this out later on. The bounding box information simply doesn't belong here. What useful purpose does it serve in the file? None. It does make it much more difficult for simple programs to write one of these files, because it makes them compute the bounding box for each object, even if they don't *use* that information themselves. Because the box includes the line width, mitering makes this a non-trivial calculation. In fact, because there's no specified limit on the length of a miter, the bounding box is _undefined_ in the general case. I want to emphasize how utterly absurd it is to store this information in an Interchange file. 1) It makes simple readers and writers more complex. 2) Even a program that could use the information can't, because 3) the information might not be correct. Since this is a published format, you can't tell where it might be coming from. A program that wants to use the bounding box to speed things up or whatever would still have to *verify* it against its idea of what the object is. And the most ridiculously redundant aspect of this whole thing is that 4) a drawing program already has to have the logic in it to compute the bounds given the parameters of an object. So why not just compute them as they get read!? Saving this information might save *some* programs a little time when reading and writing their own files, but it will cost *everybody* pain and grief in the long run. Be smart -- throw it out now. | /* 8x8 bitmap fill patterns */ /* OBSOLETE */ If it's obsolete, why publish it? | XTRN (0x4554524E) /* Externally controlled group */ It would help transportability if there was some clue what this chunk was about. | /* Color map */ | struct CMAPstruct { | LONG ID; | LONG Size; /* Usually 256*3, or 768 */ | #define NUMCOLOR(Size) (Size / 3) | UBYTE ColorMap[NUMCOLOR(Size)][3]; | }; I assume (since it's not specified) that the colors are in R G B order with 0=min intensity and 255=max intensity. If so, then this chunk is the same as the ILBM.CMAP chunk, which is probably a good thing. | RAST (0x52415354) /* Raster image */ | | struct RASTstruct { | LONG ID; | LONG Size; | IEEE XPos, YPos, /* Virtual coords */ | XSize, YSize; /* Virtual size */ | SHORT NumX, NumY, Depth; /* Actual size */ | UBYTE Colors[3*(1<