One-purpose pointer

A precision-targeted bullet: safe and efficient


ItemRef: a pointer to a globally allocated TIFF directory item. This Item:


Generic dir item being added to the directory

class TIFFNewDirItem : public TIFFDirEntry
{
  friend class TIFFBeingMadeDirectory;
  TIFFNewDirItem * next;

protected:

  class ItemRef
  {
    friend class TIFFBeingMadeDirectory;
    TIFFNewDirItem * const ref;
    TIFFNewDirItem& surrender(void)
        { return * ref; }
  public:
    ItemRef(TIFFNewDirItem * item) : ref(item) {}
  };
  virtual void write(EndianOut& file) = 0;	// Write this field into a file
  virtual void write_value(EndianOut& file) = 0;// Write additional data
  TIFFNewDirItem(const short _tag, const DataType _type,
			  const long _count, const long _value)
        : TIFFDirEntry(_tag,_type,_count,_value), next(0) {}
 };

Note that ItemRef is a wrapper around an abstract class pointer, TIFFNewDirItem*. The wrapper guarantees that the object is really inaccessible to everyone but the directory. No RTTI is necessary.


Here's where Items are inserted

They're automatically arranged in the ascending order of their tags

class TIFFBeingMadeDirectory
{
  TIFFHeader header;
  card no_entries;
  TIFFNewDirItem * first_entry;	// Other items are chained to that

public:
  TIFFBeingMadeDirectory(void);
  void operator += (const TIFFNewDirItem::ItemRef& ref);
  ~TIFFBeingMadeDirectory(void);
 void write(EndianOut& file);		// Write the entire TIFF directory
};


Using the Items

void IMAGE::write_tiff(
   const char * file_name,const char * title,
   const TIFFUserAction& user_adding_tags) const
{
  is_valid();

  message("\nPreparing a TIFF file with name '%s'\n",file_name);

  EndianOut file(file_name);
  TIFFBeingMadeDirectory directory;

  directory += ScalarTIFFDE::New(TIFFTAG_IMAGEWIDTH,
                                 (unsigned)q_ncols());
  directory += ScalarTIFFDE::New(TIFFTAG_IMAGELENGTH,
                                 (unsigned)q_nrows());
  directory += ScalarTIFFDE::New(TIFFTAG_COMPRESSION,
                      (unsigned short)COMPRESSION_NONE);
  directory += RationalTIFFDE::New(TIFFTAG_XRESOLUTION,72,1);
  if( name != 0 && name[0] != '\0' )
    directory += StringTIFFDE::New(TIFFTAG_IMAGEDESCRIPTION,
                                   name );
  user_adding_tags(directory);  // Give the user a chance to add
                                // his own tags
  directory.write(file);
  file.close();
}



The code is lifted from Appendix 2 of the paper. I thought what the heck, no one would probably make it that far, so I can quote myself occasionally.

Note the use of a class-function-pointer TIFFUserAction

The directory and file objects are allocated locally (and destroyed automatically without leaving any garbage).

Note various classes of Items: Scalar, Rational, and String items. The New() method even looks like a constructor



Next | Table of contents