This is Info file dpg-view.info, produced by Makeinfo-1.43 from the
input file dpg-view.tex.

   This file documents dpg-view.

   Copyright (C) 1992 D P Gymer

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be included in
translations approved by D P Gymer instead of in the original English.


File: dpg-view.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)

   This manual documents version 0.3.2 of dpg-view.

* Menu:

* Introduction::	Introduction and credits
* Invocation::		How to run dpg-view
* Viewing pictures::	What happens when dpg-view runs
* Adding features::	How to write functions to recognize and read other image types
* Things to do::	Things needing attention

 -- The Detailed Node Listing --

Adding features to dpg-view

* Internal overview::           Overview of how dpg-view works
* Internal structures::         Structures used by dpg-view
* Utility functions::           Useful utility functions and variables
* Image readers::               Writing code to read new image types
* Display drivers::             Writing code to handle different displays


File: dpg-view.info,  Node: Introduction,  Next: Invocation,  Prev: Top,  Up: Top

Introduction and credits
************************

   dpg-view is a program for viewing anymaps (bitmaps, graymaps, and
pixmaps)(1).  The code should be fairly portable, other than the VGA
code, which is localized to one source file.

Credits
=======

Dave Gymer (dpg@cs.nott.ac.uk)
     Original code and documentation.

Eric R Smith (ersmith@uwo.ca)
     mkptypes (used to generate the function prototypes in `proto.h').

Tommy Frandsen (frandsen@diku.dk)
     The Linux VGA library used by `view-vga.c' to plot the images.

Jef Poskanzer (jef@well.sf.ca.us)
     The pbmplus package whose image type is used for the reader in
     `read-pnm.c'(2).

David Koblas
     Much of the GIF reader, which was hacked from `giftoppm.c' in the
     pbmplus package(3).

   ---------- Footnotes ----------

   (1)  These names refer specifically to the image formats used in
the pbmplus package; dealing with other image types is possible.

   (2)  Older versions of this software (up to version 0.2.5) used the
pbmplus libraries to implement this module.  Later versions have
custom written routines.

   (3)  The following notice covers some code in `read-gif.c':

   Copyright 1990, David Koblas.

   Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.  This software is provided "as is" without
express or implied warranty.


File: dpg-view.info,  Node: Invocation,  Next: Viewing pictures,  Prev: Introduction,  Up: Top

Invocation
**********

   The arguments to dpg-view consist of the name of files in which
images you wish to be display are, and options which affect how the
images are displayed.  Options are normally given in a long form; if
an option requires an argument you should use the `=' character to
connect the option name to the argument.  Short forms of some options
also exist, but their use is discouraged(1).

   Option names may be abbreviated to their shortest unique prefix.

`-border=BORDER'
`-b BORDER'
     Don't use BORDER percentage of the screen's width and height in
     displaying an image; the resulting area to be used is in the
     center of the screen.

`-display=DEVICE'
`-S DEVICE'
     Select a different device for displaying images. This is
     dependant on the display driver; with the Linux `view-vga.c'
     driver, it gives a number from 1 to 8 which selects the VGA mode
     to use (the default for that driver is 360x480x256).  This would
     normally be a high resolution, multicolor mode, if available. 
     The display driver is at liberty ignore or cause dpg-view to die
     with a fatal error if an invalid value is given.

`-fullscreen'
     Scale the image so that it uses the full size of the screen.  Any
     aspect ratio information is ignored.

`-invert'
     Invert the colors in an image.  This is most useful with bitmaps;
     it may occaisionally be useful with graymaps, but is rarely any
     use with pixmaps (where the affect is to produce an image
     somewhat like a photographic negative).  Note that the inversion
     is done before any dithering or palette compression.

`-physical-ratio=WIDTHxHEIGHT'
`-p WIDTHxHEIGHT'
     Pretend the screen has a physical size ratio of WIDTH:HEIGHT. 
     The default is 13:10(2). This useful when dealing with images
     whose ratio is not 1:1 (that is, whose pixels are not square).

`-unscaled'
     Do not scale the image; instead, match one pixel in the image to
     one pixel on the screen.  Any image which is taller or wider than
     the screen (in terms of pixels) is rejected.  Any aspect ratio
     information is ignored.

`-version'
`-v'
     Print the version number of this copy of dpg-view and exit.  The
     number is in the form `VERSION.RELEASE.UPDATE'.

   ---------- Footnotes ----------

   (1)  Such options exist mainly to simplify the option parsing code.

   (2)  This is a good approximation for my Mitac SVGA monitor.


File: dpg-view.info,  Node: Viewing pictures,  Next: Adding features,  Prev: Invocation,  Up: Top

What happens when dpg-view runs
*******************************

   Each picture is read in and then displayed.  If at any point during
this process you hit the interrupt key, the processing of that image is
abandoned and dpg-view moves immediately on to the next image.  Hitting
the quit key will abandons the run altogether.  Otherwise, dpg-view
pauses at the end of each picture to wait for a (non-interrupt)
keypress.


File: dpg-view.info,  Node: Adding features,  Next: Things to do,  Prev: Viewing pictures,  Up: Top

Adding features to dpg-view
***************************

* Menu:

* Internal overview::           Overview of how dpg-view works
* Internal structures::         Structures used by dpg-view
* Utility functions::           Useful utility functions and variables
* Image readers::               Writing code to read new image types
* Display drivers::             Writing code to handle different displays


File: dpg-view.info,  Node: Internal overview,  Next: Internal structures,  Up: Adding features

Overview of how dpg-view works
==============================

   dpg-view works by opening each listed file in turn, and handing the
file descriptor to a set of functions, each of which is designed to
recognize a particular type of image.  *Note Image readers::, which
gives a detailed description of what such a function should do.

   If one of these functions thinks it knows how to read the file, it
attempts to do so, and returns a code to its caller to say whether or
not it succeed (failure to read and definite lack of rocognition are
treated identically).  If a function manages to read the image, no more
functions are called.  The image is read into a special structure which
gives its width and height, a color palette(1) (a list of the colors
which make up the pixels of the image), and the image itself, in the
form of an index into the palette for each pixel, thus specifying what
color each pixel is(2).  *Note Internal structures::, which descibes
this structure, and the structures which it is itself made up of.

   The image is then passed to a function which attempts to reduce the
palette size (the number of colors it contains) to a number which the
dsiplay device can show (this may not be necessary if the display can
show many colors), scales the image, and may also dither the image in
order to improve its appearance (especially if the display cannot show
many colors)(3).

   The dither code calls a function in the display driver to set the
actual display's color registers to the colors given in the (possibly
reduced) color palette, and then another function to plot each pixel
of the (possibly dithered), scaled image.  *Note Display drivers::,
where these functions are described.

   ---------- Footnotes ----------

   (1)  This is more often called a `colormap', but I like the
artistic ring of `palette', which is what they always seemed to be
called on the Atari ST.

   (2)  This is in contrast to the way in which some image file
formats, such as portable pixmaps, are stored, where each pixel has
its own red, green, and blue values.

   (3)  This doesn't actually work yet.  *Note Things to do::.


File: dpg-view.info,  Node: Internal structures,  Next: Utility functions,  Prev: Internal overview,  Up: Adding features

Structures used by dpg-view
===========================

 -- Data type: rgbval
     This is an integer variable type, with a value ranging from `0' to
     `MAXRGBVAL' (which is defined in `view.h'), which holds the red,
     green, or blue intensity of a color component.

 -- Data type: COLOR
     An integer type with a value from `0' to `MAXCOLOR' (again,
     defined in `view.h'), which is used to indicate which color out of
     a list of colors a given pixel is.

 -- Data type: struct color red green blue
     `red', `green', and `blue' are of type `rgbval', and together
     give the color of a set of pixels.

 -- Data type: PALETTE color number count next
     `color' is of type `struct color' and gives the color of all
     pixels which have a value of the `COLOR' given by `number'. 
     `count' is an `int' which is used to record the number of times a
     color occurs in a given image.  `next' is a pointer to a
     `PALETTE', and points to the next color in the list, or is a null
     pointer in the last entry.

     Each entry in the list should be unique in the value of both
     `color' and `number'.  `count' may be `0', in which case the
     color is simply discarded; the values of `number' may or may not
     form a sequence starting at 0, but it is recommended that they
     do.  No significane is placed on the order of the entries.

 -- Data type: MAP width height image palette
     `image' is a pointer to an array of `COLOR *'s, one for each row
     of the image (hence they a numbered from `0' to the value of
     `height').  Each of these is in turn a pointer to an array of
     `COLOR's having the number of elements given by `width', which
     holds the color index of each pixel (as given in a `PALETTE'
     entry).  The `palette' member points to the first entry in that
     image's color palette(1).

   ---------- Footnotes ----------

   (1)  It is not meaningful for this to be null, since each pixel
must have a corresponding palette entry, and thus an empty palette
implies an image with no colors, which cannot have any pixels.


File: dpg-view.info,  Node: Utility functions,  Next: Image readers,  Prev: Internal structures,  Up: Adding features

Useful utility functions and variables
======================================

 -- Global flag: int rc
     This holds the value which will be returned via the `exit'
     function if the program terminates normally.  By default this is
     set to `0', but can be set to some other value (normally `1') if
     an error is detected which is important but does not justify
     aborting execution.  Note that this value may be overidden if the
     program is terminated abnormally after the value is set.

 -- Global flag: int last_sig
     This is set to the number of the last non-fatal signal received
     (normally `SIGINT'), or `0'.  Functions which are likely to be
     time-consuming should periodically check for a value other than
     `0' here, and return as if they had finished normally (but
     without having actually completed the task).  For example, an
     image reader might check this at the start of every row (assuming
     pixels are read in row-by-row), and return as if the image had
     been read succesfully if a signal has been caught.

     Note that `last_sig' is reset between each image, so that an
     interrupt during the processing of one image will cause dpg-view
     to move on to the next immediately.

 -- Macro: int COLOREQ (struct color C1, struct color C2)
     Compares two variables of type `struct color' and returns 1 if the
     `red', `green', and `blue' color components of each are equal.

 -- Function: void status_bar (int DONE, int TOTAL)
     Indicate that the DONEth part of a task of TOTAL parts is
     complete.  This is normally called by image reading functions to
     let the user know that things are progressing.  Note that only
     the segment given is plotted, not the entire bar.

 -- Function: void view_message (const char *WHY, const char *WHERE,
          ...)
     Display an error or informational message on `stderr'.  WHERE,
     and any additional arguments, describe the source of the error or
     the object which information is being given about, and takes the
     form of a `printf'-style format string and arguments.  WHY
     describes the error or information itself, and is simply an
     unformatted string.  If WHY is a null pointer, then `errno' and
     `strerror' are used to determine the message.

 -- Function: PALETTE *alloc_palette (void)
     Returns a pointer to a freshly allocated `PALETTE'.  If allocation
     fails, dpg-view will abort with an error message.  None of the
     members of the `PALETTE' structure are set.

 -- Function: PALETTE *alloc_map (void)
     Returns a pointer to a freshly allocated `MAP', with its `width'
     and `height' members undefined, and the `image' and `palette'
     pointers set to null.  If allocation fails, dpg-view will abort
     with an error message.

 -- Function: void alloc_image (MAP *MAP, int WIDTH, int HEIGHT)
     Allocate a new image of HEIGHT rows and WIDTH columns, and set
     the `image', `width', and `height' members of MAP to WIDTH and
     HEIGHT, respectively.

   Prototypes for these are given in the file `view.h'.


File: dpg-view.info,  Node: Image readers,  Next: Display drivers,  Prev: Utility functions,  Up: Adding features

Writing code to read new image types
====================================

   (See `read-pnm.c' for an example.)

   Basically, you create a file called `read-FOO.c', where FOO
indicates the type of file.  Add this to the `Makefile' (both the
source name in the prototypeable source list, and the object file name
in the dpg-view object module list).  It should contain only one
externally visible identifier, which should be `maybe_read_FOO'.  Add
this identifier to the list of functions in the file `read.c'.

 -- Function: int maybe_read_FOO (FILE *FP, const char *FILE, MAP *MAP)
     FP is a stream which is opened and is positioned at the start of
     the image (normally the beginning of the file).  The load routine
     may read and seek on this stream at will, without repositioning
     the file pointer on exit.

     FILE is the name of the file for error message; you should not
     normally print messages unless you are absolutely sure that you
     have correctly identified the file type.

     MAP is a pointer to a map, with an empty palette, and no valid
     image.  If you read an image, you must fill the palette, and
     allocate (using `alloc_image') and fill the image.

     The function should return 0 if it recognizes the image and has
     succesfully loaded it, or 1 othewise.

   On entry to the function, the `image' and `palette' members of the
`MAP' structure are initialized as null pointers.

   On exit from the function, the structure members should be set like
this:

`width'
`height'
     These are normally set by `alloc_image', and should not be altered
     by modules after an image has been allocated.

`image'
     If the function returns 0, this must be set to point to an image
     (normally allocated with `alloc_image').  Otherwise, it need not
     be set.

`palette'
     This should be a pointer to the first element in a linked list of
     colors (each element normally being allocated with
     `alloc_palette'.

   During reading, it is useful to use the `status_bar' function to
let the user know how the read is progressing, since large images may
take some time to read.  (If the image format is guarenteed to be
small, such as the uncompressed X-Face, this may be ignored.)


File: dpg-view.info,  Node: Display drivers,  Prev: Image readers,  Up: Adding features

Writing code to handle different displays
=========================================

   (See `view-vga.c' for an example.)

   The file should be called `view-FOO.c', where FOO describes the
display device.  Add the source file name to the Makefile in the
prototypeable source list.  The appropriate object filename should
replace the default display driver in the program target's list.

   It should provide the following functions.  No other identifiers
should be externally visible.

 -- Function: int readkey (void)
     Read a keypress.  Echoing and line buffering should be disabled. 
     Return the key pressed, or EOF.

 -- Function: void plot_pixel (int X, int Y, COLOR C)
     Plot a pixel of color C at row Y of column X.

 -- Function: int init_display (int *WIDTH, int *HEIGHT, int
          *NUM_COLORS)
     Initialize the display, and set the integers pointed to by WIDTH,
     HEIGHT, and NUM_COLORS to apropriate values.  The function should
     return 0 if succesful, non-zero otherwise.  If the terminal
     parameters are altered, care should be taken to leave the
     interrupt and quit keys (if available) active.

     The variable `screen_dev', which is of type `const char *',
     points to the display device given in the options to dpg-view, or
     0 if none was.  The display driver may use this value to select a
     particular display mode (in which case none is given, a sensible
     default should be chosen), or it may simply ignore it (for
     instance, if only one display mode is available).

 -- Function: int set_colors (PALETTE *PAL)
     Set the display's color registers to those given in the list
     whose first entry is pointed to by PAL.  The `number' field gives
     the register number, and the `color' structure gives the red,
     green, and blue component values, from 0 to `MAXRGBVAL'.  The
     number of colors will never exceed the maximum number indicated by
     `init_display'.

 -- Function: void tidy_display (void)
     Return the display to the state it was in before init_display was
     called.


File: dpg-view.info,  Node: Things to do,  Prev: Adding features,  Up: Top

Things to do
************

   Add dithering and palette compression capabilities.  The current
`dither()' function merely scales the image; it doesn't compress the
palette or dither the image.

   Pass the name of the image file to all the functions that deal with
it and might give an error, so that we can tell the user which image(s)
failed to diplay properly and why.  (This is just because of my quickly
written image reading code.)

   Check arguments more carefully.

   Read other common formats, such as PCX.  *Note Image readers::

   Re-write the GIF reader to recognize extension blocks, and to stop
being dependant on someone else's code (not that it _really_ matters,
I'd just be happier about it if it were under the GPL).

   Re-write the uncompressed X-Face reader to be able to uncompress the
images, maybe even pull them out of mail and news messages.

   More speed might be gained if, after we display and image, we just
flush the input buffer, and only wait for a key once the next image is
loaded and ready for display.  This may or may not cause unwanted
trouble with SIGINTs and the status bar.  More thought required, I
think.

   Option to force color images to grayscale.  This would save us using
ppmtopm on very colorful images.  This might also be the best way to
deal with images with more gray levels than we actually distinguish or
can display, and saves us mucking around with unnecessary dithering.

   The ability to display images larger than the screen in a scrollable
window.



Tag Table:
Node: Top858
Node: Introduction1660
Node: Invocation3309
Node: Viewing pictures5856
Node: Adding features6380
Node: Internal overview6887
Node: Internal structures9128
Node: Utility functions11346
Node: Image readers14561
Node: Display drivers16922
Node: Things to do19086

End Tag Table
