[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Endian-ness



John Ivens wrote:
> 
>    Part 1.1    Type: Plain Text (text/plain)
>            Encoding: 7bit

I'm including this in my reply to show the difficulty I have with John's
email: I receive effectively an empty message with a text attachment.
Since the attachment is not included in the reply I have to cut and
paste it in. Yes, I know about the vagaries of email software. It would
just be convenient if I could receive plain text as ... plain text.

-- 

Bradford Castalia                       Castalia@Arizona.edu
Senior Systems Analyst                  http://PIRL.LPL.Arizona.edu/~castalia
Planetary Image Research Laboratory     520-621-4824

"Build an image in your mind, fit yourself into it."
    The Log of Cyradis, Seeress of Kell.


John Ivens REALLY wrote:

I think that the PDP constant indicates that its ultimately
insufficient, and yet how many machines are neither
LITTLE nor BIG endian?  Very few machines in current use, I would
suspect.  So I think we can declare victory on
that point.

>>>
Not so fast. If we have only one case of someone wanting to take
advantage of the ICL using a "different" architecture, that's
reason enough to support it. I always cringe at the idea that what
is good enough for the majority is good enough. This is, to be crass,
the Microsoft way. A better justification for the same immediate
outcome is that we are building ICL lite; getting it working with
what we've got. But plan for the complete solution; in the long run
those minority cases are just as important as the more common ones
(I happen to own a fully functional PDP-11/34A - supporting a
Gould/DeAnza IP8500 image processing hardware subsystem, if you want
to talk about really exotic - with which I made a decent livelihood
as an independent contractor for many years; thank you very much 8^).
In the long run its the minority that leads the way for the majority.

So I think we can declare OK for now. This was what I did for xv.
But as you are writing code try to keep in mind how the general
problem might be solved and where it is likely to impact your code.
For a support technology like ICL there needs to be a broader base
of architecture compatibility than for most application software.
If we are successful - we will be, ya - we will need to cross this
bridge at some point.
<<<

Work is progressing (although slowly) on the pixel representation
front.  Dyer and I were talking about needing an
interrogator object but not wanting the user to have to instantiate
one.  I think the solution is on page 253 of
Stroustrop where he talks about a first-time switch for local static
objects to make sure that they are initialized.

>>>
I've looked at the Stroustrup reference and agree that a "first time
switch" is appropriate. I use them a lot in what I've developed.
However, I also agree with Stroustrup's expansion of this topic in
Section 21.5.2: It is best to put the switch in a central location
rather than incur its expense in oft used functions. I'm also in the
habit of doing what Stroustrup does: incorporating the first time
switch into a variable this is used for some other purpose anyway.
I think that the Image object instantiation ID variable could make an
suitable first time switch in much the same was as Strustrup uses the
counter variable in his iostream example.

The initialization of the interrogator would be done in the Image
object constructor (still very much pseudocode):

class Image
{
private:
    static unsigned long next_ID;
    unsigned long ID;
public:
Image ();
};

unsigned long Image::next_ID = 0;

Image::Image ()
{
if (! (ID = next_ID++))
    {
    // Initialize the environment, including the Iterrogator.
    ...
    }
...
}

<<<

// Warning -- this code is really pseudocode!!  It is untried!!  The
driverList is not fully
//                         implemented!!
//                          The actual initialization trick will work,
however.

>>>
Let's take advantage of namespaces: "ICL" sounds appropriate for now.
So instead of ICL_XXX in the old C naming fashion we have "namespace ICL {"
or ICL::XXX.
<<<

class ICL_Interrogator {
    static bool initialized;
    static bool initialize(dList driverList) {
        /* initialize */ initialized = true;
        // Do other initialization work for this class, like finding all
of the mini-drivers
        // locations from a specified file and loading them into an
array or some structure
    }
  public:
    // no constructor

    void interrogate(string &Buffer) {
        if (initialized == false) {
            initialize(driverList);
        }
        // Now do the real work of interrogating each driver
        // Loop through the driver array asking each one if this file is
theirs
        // This driverList is some kind of list-like object, now
PSEUDOCODE
        for (i=driverList.begin(); i<driverList.end(); i++) {
            if ( *Buffer.length() < *driverList[i].neededBufferSize() )
{
                // Allocate needed buffer size here
                // This brings up a question -- can we assume that the
drivers are smart
                // enough to work with C++ strings?  Will this need to
be turned into a c_str()?
>>>
It's important that we make as few assumptions as possible about how a
driver will be written. In addition, it's important that the necessary
contraints that are imposed by the interface specification be as easy
as possible to work with (as language neutral as possible). It seems
reasonable to pass "strings" as null-terminated char arrays.
<<<
            }
            if ( *driverList[i].belongsToMe(Buffer) )  {
<<<
How about:

The_File_Info = new File_Info (filename /* or whatever */);
foreach driver (driver_list)
  {
  // The driver object updates the buffer in The_File_Info as needed.
  if (driver.recognizes (The_File_Info))
    The_Driver = driver, break;
  }
if (! The_Driver) // Because it is initially null.
  throw Image_Open_Exception;

Note that The_Driver object encapsulates whatever information is needed
to interface with the driver - including the specific driver's own data
block - and the interface methods on a driver.
<<<
                // Implementation question (raised by Dyer):
                // Should the last chosen file type be propagated to the
top of the list of
                // queried drivers?  This would mean if the user wanted
to open 100 images in a
                // row, and get a pixel out of each one, and each file
was the same type
                // (like VICAR), then each file after the first one
would be read in as quickly as
                // possible because the VICAR driver would be the first
one checked.

>>>
Good question. I would generalize this into the issue of driver list
management. It seems that there will be numerous operations that both
the ICL and the user may want to do on the list including reordering
the list based on an application provided configuration file, keeping
track of the last used driver and using this first instead of the default
order based on a mode setting, adding and dropping entries to the list
in addition to the usual querying, providing the list in a form suitable
for inclusion in a text configuration file, etc.
<<<

                return (&driverList[i].driver());
        }
        // No driver matched -- return unknown
        return (NULL);
<<<
Shouldn't an exception be thrown instead of NULL returned (here we go again)?
<<<
    }
}


So the user does something like:

ICL_Image iclm = new ICL_Image("this_file");

The constructor for ICL_Image does something like this:

ICL_Image::ICL_Image(string fileName) {
    // blah blah, make buffer of default size, blah blah
    string Buffer[256];
    // Note that we don't have to instantiate the ICL_Interrogator
class, it initializes itself
    // This means that the driver file only needs to be read once.
    driver theDriver = ICL_Interrogator.interrogate(Buffer);
    // We don't know what size the Buffer will be when it returns...
    header theHeader = theDriver.readHeader(Buffer);
}

This will then allow interrogation of the header and further reading of

>>>
I don't think the ICL core should know anything about "headers". This is
the driver's business. The ICL knows about image attributes and pixel data
but always uses the driver to obtain them. In writing a driver I would
probably read the entire header into a data block in a form optimized for
later use (e.g. as a PPVL hierarchy) and attach this (as a pointer to
where the data is in memory) to the driver data block carried around by
the Image object. It will be there for me when the ICL passes the driver
data block (again as a reference) to me over the interface.

For the initial interrogation, however, I (as a small module related to,
but separate from the main driver module) will do as little as possible
to determine if The_File_Info refers to a file that I know about. Perhaps,
if I do recognize the file, I will invoke the main driver module and
initialize it (which could then read the entire header), returning a
fully initialized driver to the ICL core. This would obviate the need
for a first time switch in the main driver module.
<<<

the file contents.  More to come...  and this
will probably change into a better object model when you guys review
this... :)

--
When I use a word it means just what | John Ivens
I choose it to mean - neither more   | Principal Programmer
nor less.                            | Cassini VIMS
-- Humpty Dumpty                     | (520) 621-7301