// Disclaimer

In this document, I will say "should" a lot, as in the way things
"should" be done.  That doesn't mean I'm trying to dictate dogma --
I'm just stating an opinion for discussion purposes.  That said,
here's the vision...

// Project Scope

Although we're developing on linux, there's no reason why our code
shouldn't be aimed at generic unix.  Where feasible, we should avoid
linux-specific conventions, device names, driver properties, etc.  We
should stick to POSIX where possible and relevant.  I don't mean that
we should start testing on multiple unixes right away, but that we
should try to make it easy to port to other unixes when that time
comes.  For example, where we do byte-swapping of 16-bit and 32-bit
quantities, we should wrap the code with ifdefs, to ease porting to
big-endian unixes.

The Host Interface Specification (HIS) we're working from is a
Flashpoint publication -- nowhere in it is Kodak mentioned by name.
So, although we're developing for Kodak cameras we should make it our
goal to support any Digita-equipped camera.  The Minolta EX 1500
cameras will use Digita, and the Flashpoint web page lists Sharp as a
manufacturer, so we may be seeing Digita cameras from them too.
Following the HIS should ensure that we're compatible with these
products, and we should take pains not to make our code, comments, or
doco too Kodak-specific.

// Products

As I've mentioned in previous e-mail, we should start small, with a
core library, then build new products around that core.  Here, then,
from low-level to high-level are the products I envision for camera
support and somewhat beyond.

Digita interface: The core library that speaks the wire protocol to
		the camera, and provides convenient access to camera
		function primitives from C code.  This library should
		come first, although it need not necessarily be 100%
		finished before other products emerge.

Bindings:	Access to the camera from perl, C++, Java, Python.
                These will vary in complexity: C++ binding should be
                fairly easy.  Java will require JNI and be necessarily 
                more complicated.  Perl and Python probably lie
                between C++ and Java in complexity.
                
SANE module:	A GNU Image Manipulation Program (GIMP) plug-in to
                allow the GIMP to download files directly from the
                camera.

Command-line utility: A simple program, or suite of programs designed 
                to move data to/from the camera from the command
                line.  This product might have about the same feel as
                the mtools -- mdir, mcopy, etc., that provide access
                to DOS floppies (that's *not* to suggest that the
                command-line utility should have a similar syntax).

EXIF utility:   Not really a camera utility, but it would be useful to 
                the same users, hence I include it under the project
                umbrella.  The JPEG files downloaded from a Digita
                camera have an EXIF file embedded in them as a JPEG
                application extension (APP1 or APP2, I believe).
                Camera users would like to have a utility to extract
                and display this information from the JPEG file.  The
                EXIF file includes the date and time the photo was
                taken, the camera settings (flash, f-stop, lens), the
                photo serial number, etc.

camerafs:	A virtual filesystem for linux.  Image being able to
                "mount" your camera as a linux filesystem, and
                manipulate the camera's images and albums as if they
                were linux files and directories:

                    %mount /dev/cua2 /camera -t camerafs -o donly
                    %cd /camera
                    %ls 
                    album1/  p0000100.jpg  p0000101.jpg  system
                    %ls album1
                    p0000102.jpg
                    %cp *.jpg album1/*.jpg ~/dc-260/
                    %ls ~/dc-260
                    p0000100.jpg p0000101.jpg p0000102.jpg
                    %rm -rf *.jpg album1

GTK utility:	A tool similar to Kodak's bundled DC-220/260 image
                browser, with a slick GTK user interface, but less
                fluff and more function than Kodak's.  Drag-and-drop
                interactivity with GIMP, and perhaps hooks into GIMP
                scripting.

The following two products are not built from the Digita libraries and
are not limited to digital-camera users.  I list them here because I
see them as being part of the continuum of image-manipulation tools,
with libraries like the Digita interface and imlib at the low end, and
tools like the GIMP at the high end.  The following products would
complement the GIMP both for digital photographers and digital
artists.

image versioning:  A command-line tool similar to RCS, but for
		tracking version histories of images instead of source
		files.  Does not record literal source differences as
		does RCS, but the editing commands used to create one
		version from another.  Will use a GIMP plug-in to
		track and record user changes to an image; the
		resulting differences can be stored in an external
		version file, or in the image file as JPEG application
		extensions.

		The purpose of this tool is to cut down on the file
		clutter that results as an image is worked on through
		its life-cycle.  For example, when I scan a photo, I
		go through several standard iterations, and I like to
		keep the image resulting from each: the raw scan, the
		version with scratches and specks removed, the version
		that I crop and color-correct, the web-friendly
		(scaled down to 640x480) version, and the web
		thumbnail.  An image versioning tool would allow all
		versions of an image to be kept in a single file for
		archival and management purposes.

PhotoNav:	A companion to the GIMP -- a GTK/GNOME tool for managing
		collections of images.  Will include an image browser,
		and an image history viewer.  Will have hooks into the
		image versioning tool for managing image revisions,
		and will have hooks into the GIMP for editing.  GNOME-
		aware, so it will support drag-and-drop to the GIMP
		and to filesystem browsers.  Will have guile scripting 
		so that tasks can be automated.

// Development Strategy

At the heart of all the camera products is the Digita interface
library; our first effort should (and has been) dedicated to this body
of code.  However, our users (and ourselves) have an itch: to get
photos from linux.  It is important for our first release to scratch
that itch, even if only with limited functionality.

My proposal is that our first release goal should be a well-engineered 
library accompanied by a utility to download images from the camera.
This will "scratch the itch" of linux users wanting to download from
their cameras without having to boot into Windows, and should get our
project off to a nice start in our end-users' eyes.  We should procede 
along these lines:

1.  Perform proof-of-concept prototyping to demonstrate that we can
    communicate with the camera and understand its protocol.  This has
    already been partly accomplished.

2.  Design an API for the library, and code the header files
    declaring the API.  See the API section below for thoughts on how
    we should structure the library and its API.

3a. Begin implementation using the prototype sources if they are
    suitably well-organized, discarding them and starting from scratch
    otherwise.  In parallel with this we can begin two other
    activities:

3b. Begin design and implementation of the EXIF library, focusing on
    API design and on the code needed for support of the command-line
    utility.

3c. Begin implementation of the command-line camera utility.  This can 
    be done in parallel with 3a by writing stub libraries and using
    them until the core library becomes mature enough to use.

4.  When the three components become mature enough that they can
    reliably copy images from the camera, we release our first
    versions of the libraries and utility.  Note that, because we've
    very narrowly defined what the first release can do, we should be
    able to reach it fairly rapidly -- within a month or two.  The
    first-release goals for the three components are:

    Digita library: can contact the camera over serial port, retrieve
    list of pictures, download pictures.  Minimal error checking.

    EXIF library: can scan the JPEG image for embedded EXIF; can scan
    EXIF for date/time of photograph.

    Command-line app: uses Digita library to download images from
    camera and store to local file system.  Uses EXIF library to
    retrieve date and time of photograph, and set creation times of
    files appropriately.

Further development to be defined.    

// Digita Library API

The API has three parts: first, the environmental part which sets up a
camera "environment" by establishing a connection to a camera; next,
the "common" part which corresponds to the Core Commands listed in
chapter three of the HIS, pp 27-50; finally, the "low-level" part
provides a means of talking directly to the camera.  A possible fourth
part "product-specific" might be considered eventually, but is beyond
the present scope of the project.

All Digita library API calls use a DLCamera structure; this structure
is opaque to client code (in OO terms we have data encapsulation).  To 
communicate with a Digita camera, one first gets a DLCamera pointer
representing that camera:

    DLCamera camera = DLOpenCameraNSS("/dev/cua2");

All commands interacting with the camera then pass the DLCamera
pointer as a first argument:

    DLPowerState pstate;
    DLGetPowerMode(camera, &pstate);

The Environmental API creates, configures, and destroys DLCamera
pointers; the Common and Low-level APIs perform operations on them.

// Environment API

Several calls are provided to open camera connections:

    DLCamera *DLOpenCameraNSS(const char *dev_name);
    DLCamera *DLOpenCameraUSB(const char *dev_name);
    DLCamera *DLOpenCameraIrDA(const char *dev_name);
    DLCamera *DLInitialize(int *argc, const char *argv[]);

DLOpenCamera* opens a camera at a specific device.  DLInitialize opens
a camera after scanning the command-line and environment variables to
determine which device to open.  DLInitialize will enable Digita
Library utilities to share a common command-line syntax and common use
of environment variables without each application having to code its
own.

This is similar to the way X applications specify which X server to
connect to: they can specify it on the command-line:

    xterm -display localhost:0

Or by setting an environment variable:


    DISPLAY=localhost:0 xterm

For Digita libraries, the intent is similar, but we should use
GNU-style arguments:

    camutil --dldevice=/dev/cua2

We will also examine environment variables:

    DLDEVICE=/dev/cua2 camutil

DLInitialize can also scan other connection parameters from the
command-line and environment.  For example, the maximum time the
library waits to connect to a camera, its timeout value, might be
specified on the command-line:

    camutil --dltimeout=2

To specify a timeout of 2 seconds, or in the environment:

    DLTIMEOUT=2 camutil

The environmental API will also provide calls to specifically
configure parameters such as timeout:

    void DLSetTimeout(DLCamera *camera, unsigned int timeout);

// Common API

Flashpoint structured their HIS documentation so that camera commands
look like API calls, and the Common API calls should directly reflect
this.  Each API call will take, in order, the camera pointer, the
input arguments, and the output arguments.  Input arguments will be
integral types or const pointers; output arguments will be integral
types or non-const pointers.  Each call will return a value indicating 
whether the command completed, or encountered an error.

The exemplar function listed on HIS p19 is:

    CommandName(ReqArgList) -> (ResArgList)

This would become, for the Digita library API:

    DLResult DLCommandName(const ReqArg1 *in1, const ReqArg2 *in2, ...,
                           ResArg1 *out1, ResArg2 *out2, ...);

Allocating space for input and output arguments is the responsibility
of the caller; the Digita library never allocates-and-returns.

The character primitive types PName, DOSName, ShortStr, and String
will be represented by C strings (arrays of char).

// Low-Level API

The Low-level API will provide client code a lower level of access
than the Common API.  Precisely how it should be structured isn't
clear at the moment, but it is clear that *somebody* will eventually
voice the comment that "the Common API doesn't do everything I need
to" or "doesn't do it the way I want to".  The low-level API gives
these users the ability to talk directly to the camera.  We will
probably create the low-level API simply by exposing and documenting a 
subset of the library's internal functions.

// Devices

My reading of the HIS is that the protocol is independent of the
transport layer.  In other words, the NSS, USB, and IrDA versions of
the library can be the same except for the code that establishes
communication with the camera, and sends and receives messages.

Initial development will be with the serial port, but we want to be
able to also support USB and IrDA without having to change the API or
the internal structure of the library.  In C++ this would be easy --
we'd define an abstract class representing the connection to the
camera, and defining virtual functions such as readMessage and
writeMessage.  

We can approximate this in C using a struction with function pointers,
through which the core library makes calls to read or write the
camera.  The idea is the same: to provide an abstract interface so
that the core library doesn't have to know or care whether what the
underlying transport layer is.

// Project Name

We need a project name.  This can be fun, but it can also be kind of
contentious, because here opinions will vary the most widely.  

An ideal project name would combine elements of open-source, camera,
digita and/or unix.  Or at least suggestions of the same.

We should avoid names like "Project 220" because they suggest that we
support only the DC220 or only Kodak cameras.  We also want to avoid
infringing on trademarks, because that brings lawyers,
cease-and-desist letters, and other unpleasantness -- and in the end,
we'd have to end up changing the project name.

Here are the results of my brainstorming on the Project Name issue:

"Open Camera" or "Open Camera Initiative".  Symbolic but bland.
Suggests Open and Camera.  A web search turned up no obvious
trademarks, but there is an "Open Camera" webcam in Zagreb.

"DigitOpen".  Suggests Digita and Open.  Doesn't really roll off
the tongue.

"FlashOpen".  Suggests Digita (Flashpoint) and Open.  But doesn't
really suggest cameras.  Sounds more like the way a magician opens a
box.

"Digitalux".  My favorite.  Suggests Digita and Linux ("-ux").  Rolls
off the tongue.  Downside: there's a theatre production company called 
Digitalix.  We could probably avoid trademark questions in that the
two are spelled differently, and related to different fields.

"Talux".  A truncation of Digitalux.  Cryptic, but catchy.

"Project Rochester".  Named after Kodak's headquarters.  Not directly
tied to Kodak, but suggestive of the project origins (which is OK).
My least favorite of the project names, but might be recycled as a
"code name" for our first release.  Subsequent releases could be named
for other NY cities: Ithaca, Syracuse, Geneva, Auburn, etc.

// Publicity

We need to establish a web site to provide information about the
project, and to distribute code releases (though we can also allow
anonymous access to our CVS repository).  The web site does not have
to fancy, but should include background information about the project
-- our goals and approach (perhaps a rewrite of this document).

I have found a site that offers free web support to open-source
projects, and as soon as we have selected a project name, I will apply 
for an account.  We also need to set up bug-tracking; the site
announced in slashdot recently will do.

When we have reliably functioning code, a basic web site, and bug
tracking, we can make our first announcement to Freshmeat.

// Licensing

All the standalone programs should be GNU General Public License
(GPL).  For libraries, we have the option of choosing the GNU Library
General Public License (LGPL).  My preference would be to GPL the
libraries, but could be persuaded to the LGPL.
