Annotation of researchv10dc/vol2/graphics/picfile.ms, revision 1.1

1.1     ! root        1: .so ../ADM/mac
        !             2: .XX 36 571 "A Research Picture File Format and I/O Library"
        !             3: .fp 5 T CW     \" T for Typewriter
        !             4: .TL
        !             5: A Research Picture File Format and I/O Library
        !             6: .AU
        !             7: Tom Duff
        !             8: Don Mitchell
        !             9: .AI
        !            10: .MH
        !            11: .SP
        !            12: .2C
        !            13: .NH
        !            14: Introduction
        !            15: .PP
        !            16: Researchers in centers 1122, 1125 and 1127 have for several years used
        !            17: a general file format for storing digital images,
        !            18: depth maps, mattes, and other two-dimensional digital signals.
        !            19: We have a convenient, portable library of C-language functions for
        !            20: manipulating picture files and a rapidly growing collection of graphics
        !            21: and image-processing software that uses the picfile format and library.
        !            22: .1C
        !            23: .KF bottom
        !            24: .P1 0
        !            25: TYPE=dump
        !            26: WINDOW=0 0 512 512
        !            27: NCHAN=1
        !            28: CHAN=m
        !            29: COMMAND= antiquantize 'halftone CLASSIC' 512.halftone LIBERTY.anticlassic 
        !            30: COMMAND=  halftone CLASSIC 512.liberty 512.halftone 1.75 512.halftone 
        !            31: COMMAND=   transpose IN OUT 
        !            32: COMMAND=    resample 512 IN OUT 
        !            33: COMMAND=     transpose IN OUT 
        !            34: COMMAND=      resample 512 IN OUT 
        !            35: COMMAND=       clip 400 400 LIBERTY OUT
        !            36: .P2
        !            37: .ce
        !            38: Figure 1
        !            39: .KE
        !            40: .2C
        !            41: .NH
        !            42: The File Format
        !            43: .PP
        !            44: A picture file (often called a `picfile') contains a variable-length ascii header
        !            45: followed by a optional color-look-up table
        !            46: and binary data representing a two-dimensional array of multi-byte pixels.
        !            47: .PP
        !            48: The header is a list of attribute/value pairs
        !            49: separated by newlines, terminated by an
        !            50: empty line.  A pure ascii header is
        !            51: machine independent.
        !            52: Its open-ended form allows applications to annotate pictures
        !            53: any way that they wish.  Figure 1 shows a typical header.
        !            54: Each header line is of the form
        !            55: .I `attribute=value'
        !            56: where
        !            57: .I attribute
        !            58: is any string not containing an equal sign `=', an ascii nul (zero byte), or a
        !            59: newline, and
        !            60: .I value
        !            61: is any string not containing a newline or nul.  The newline-terminated
        !            62: entries are separated from the binary data by an empty line (i.e. a pair of newlines).
        !            63: Thus,
        !            64: .P1 0
        !            65: sed '/^$/q' \fIfilename\fP
        !            66: .P2
        !            67: will print a picfile's header.
        !            68: .PP
        !            69: Several attributes are mandatory.
        !            70: The
        !            71: .CW TYPE
        !            72: attribute
        !            73: .I must
        !            74: come first,
        !            75: acting as a ``magic number'' and specifying the binary encoding of the
        !            76: image data.  Currently, five binary formats are supported:
        !            77: .IP \fTTYPE=dump\fP 5n
        !            78: .br
        !            79: The binary data follows in traditional scan-line order.
        !            80: The first pixel in the file is at the upper left corner of
        !            81: the image.
        !            82: .I X
        !            83: coordinates increase to the
        !            84: .I right
        !            85: on a
        !            86: display, and
        !            87: .I y
        !            88: coordinates increase
        !            89: .I down.
        !            90: Pixels are stored in row-major order (i.e.,
        !            91: .I x
        !            92: increases faster than
        !            93: .I y ).
        !            94: .IP \fTTYPE=runcode\fP
        !            95: .br
        !            96: Each pixel is preceded by a one-byte count that indicates how many adjacent
        !            97: pixels have the given value.  Count
        !            98: values of 0 to 255 represent a replication factor of 1 to 256.  No
        !            99: run may extend from one scan-line to the next.
        !           100: This format is useful in reducing the size of mattes or pictures containing
        !           101: large areas of constant color, but it may be a poor choice for digitized
        !           102: natural images or pictures containing noise.
        !           103: .IP \fTTYPE=bitmap\fP
        !           104: .br
        !           105: Pixels are one bit each, packed
        !           106: 8 bits to a byte, with the leftmost pixel in the high-order bit of
        !           107: the first byte.  Each row must be an even number of bytes,
        !           108: so there can be up to 15 zero bits after the right-most pixel.
        !           109: A bit value of 1 represents black; 0 represents white.
        !           110: This is exactly the encoding used by SUN Microsystems and compatible
        !           111: manufacturers.
        !           112: .IP \fTTYPE=ccitt-g4\fP
        !           113: .br
        !           114: A black-and-white image encoded according to the CCITT FAX Group 4 standard.
        !           115: This is highly compressive on printed text and sparse line-graphics.
        !           116: .IP \fTTYPE=ccir601\fP
        !           117: .br
        !           118: The image is encoded according to the IEEE digital component video standard.
        !           119: (Y,U,V) values are stored as 8-bit values with chrominance compressed to half
        !           120: as much bandwidth as luminance.  The layout of each row is
        !           121: Y U Y V Y U Y V ...
        !           122: .LP
        !           123: The other mandatory attribute is:
        !           124: .IP "\fTWINDOW=\fIx0 y0 x1 y1\fR"
        !           125: .br
        !           126: Specifies the size of the image by the
        !           127: coordinates
        !           128: .I "(x0, y0)
        !           129: of the upper left
        !           130: corner of the picture and
        !           131: .I "(x1, y1)
        !           132: of the pixel one beyond the lower right.
        !           133: The C interface uses
        !           134: .I "x0, y0, width, height
        !           135: to avoid confusion about whether
        !           136: the corner is in or out of the picture.
        !           137: .LP
        !           138: For
        !           139: .CW TYPE=dump
        !           140: and
        !           141: .CW TYPE=runcode ,
        !           142: the following attribute is mandatory:
        !           143: .IP \fTNCHAN=\fInbytes\fR
        !           144: .br
        !           145: Specifies the number of bytes in each pixel.
        !           146: .CW TYPE=bitmap
        !           147: and
        !           148: .CW TYPE=ccitt-g4
        !           149: may optionally take
        !           150: .CW NCHAN=1 ,
        !           151: and
        !           152: .CW TYPE=ccir601
        !           153: may optionally take
        !           154: .CW NCHAN=3 .
        !           155: .LP
        !           156: It is conventional but not mandatory to include:
        !           157: .IP "\fTCHAN=\fIformat\fR"
        !           158: .br
        !           159: Specifies the internal structure
        !           160: of a pixel.
        !           161: .I Format
        !           162: is a string of length equal to the value of
        !           163: .CW NCHAN .
        !           164: For example:
        !           165: .RS
        !           166: .IP \fTCHAN=rgb\fP\ \ 
        !           167: 24-bit red-green-blue pixel.
        !           168: .IP \fTCHAN=rgbz...\fP\ \ 
        !           169: 24-bit red, green and blue
        !           170: entries and a 32-bit depth
        !           171: value (floating point).
        !           172: .IP \fTCHAN=m\fP\ \ 
        !           173: 1-byte monochrome or
        !           174: color mapped values.
        !           175: .RE
        !           176: The picfile routines specified here do
        !           177: not care how the user names channels.
        !           178: However, there are some conventions:
        !           179: .RS
        !           180: .IP \fTrgb\fP
        !           181: red, green, and blue channels
        !           182: .IP \fTyiq\fP
        !           183: NTSC luminance/chrominance channels
        !           184: .IP \fTyuv\fP
        !           185: IEEE or PAL luminance/chrominance channels
        !           186: .IP \fTa\fP
        !           187: alpha channel (matte)
        !           188: .IP \fTm\fP
        !           189: monochrome or mapped value
        !           190: .IP \fTf...\fP
        !           191: dots indicate a
        !           192: multiple-byte channel (e.g. a floating-point number)
        !           193: .RE
        !           194: .IP "\fTCOMMAND=\fIcommand line\fR"
        !           195: .br
        !           196: Store picfile history information.
        !           197: Multiple
        !           198: .CW COMMAND
        !           199: entries may be present in the header.
        !           200: The first is the command line used to make
        !           201: this picture, and following it are the
        !           202: .CW COMMAND
        !           203: entries (indented by one space) from
        !           204: all picfiles opened before this header
        !           205: was written.
        !           206: The header in Figure 1 shows
        !           207: a picture clipped to 400\(mu400, digitally
        !           208: resampled to 512\(mu512, converted to bitmap
        !           209: by a halftone screen, and then converted
        !           210: back to gray-level by Wiener-filter
        !           211: reconstruction.
        !           212: .IP "\fTRES=\fIxres yres\fR"
        !           213: .br
        !           214: Specifies the horizontal and vertical resolution in pixels per inch.
        !           215: This attribute is often used for images of documents.
        !           216: .IP \fTCMAP=\fP
        !           217: .br
        !           218: The
        !           219: .CW CMAP
        !           220: attribute has no value associated with it.  It flags
        !           221: the presence of a color-look-up table after the header.
        !           222: This table is 768 bytes long and consists of 256 values of red, green,
        !           223: and blue.
        !           224: The bytes of the
        !           225: colormap are stored as rgbrgbrgb...
        !           226: .LP
        !           227: The colormap should be loaded into the frame buffer's
        !           228: colormap when the image is displayed.
        !           229: The mapping from pixel channels to colormap values
        !           230: in a full-color (e.g.
        !           231: .CW CHAN=rgb )
        !           232: picture is usually:
        !           233: .P1 0
        !           234: displayed red   = colormap[3*r + 0]
        !           235: displayed green = colormap[3*g + 1]
        !           236: displayed blue  = colormap[3*b + 2]
        !           237: .P2
        !           238: In a monochrome picture, channel
        !           239: .CW m
        !           240: is normally mapped:
        !           241: .P1 0
        !           242: displayed red   = colormap[3*m + 0]
        !           243: displayed green = colormap[3*m + 1]
        !           244: displayed blue  = colormap[3*m + 2]
        !           245: .P2
        !           246: Applications may add other header lines.  It is perfectly
        !           247: permissible to include
        !           248: .CW SHOESIZE=10
        !           249: in the header, which all
        !           250: standard software will pass uninterpreted.
        !           251: .PP
        !           252: Following the ASCII header and the optional colormap is the
        !           253: binary data for the image.
        !           254: The routines described below assume nothing about this data
        !           255: except what is specified by
        !           256: .CW TYPE ,
        !           257: .CW WINDOW
        !           258: and
        !           259: .CW NCHAN .
        !           260: .PP
        !           261: Pixels
        !           262: .I N
        !           263: bytes long, where
        !           264: .I N
        !           265: is the value of the
        !           266: .CW NCHAN
        !           267: attribute.
        !           268: .I Picread
        !           269: and
        !           270: .I picwrite ,
        !           271: described below, do not interpret pixel values, except for conversion to
        !           272: a uniform format.
        !           273: Higher level software must assign format and meaning to
        !           274: pixels and specify byte ordering
        !           275: of short or long integers and the format of floating point data.
        !           276: .NH
        !           277: The Picfile Library
        !           278: .PP
        !           279: Picture files are referred to by a pointer to a
        !           280: .I PICFILE
        !           281: data structure,
        !           282: analogous to the standard I/O library's
        !           283: .I FILE
        !           284: structure.  There
        !           285: are just a few routines for opening, reading and writing
        !           286: picture files one scan line at a time.  To use them, a program
        !           287: must include the header file
        !           288: .CW picfile.h .
        !           289: On 10th edition
        !           290: .UX
        !           291: systems this file is in
        !           292: .CW /usr/include .
        !           293: On center 1125's SUNs it may for
        !           294: administrative reasons be found elsewhere.
        !           295: .P1 0
        !           296: PICFILE * picopen_r(char *filename);
        !           297: .P2
        !           298: .P1 0
        !           299: PICFILE * picopen_w(char *filename,
        !           300:        char *type, int x0, int y0,
        !           301:        int width, int height, char *
        !           302:        chan, char *argv[], char *cmap);
        !           303: .P2
        !           304: .I Picopen_r
        !           305: opens a picture file for reading;
        !           306: .I picopen_w
        !           307: opens it for writing.
        !           308: For both routines,
        !           309: .I filename
        !           310: is usually a name of a
        !           311: .UX
        !           312: file.
        !           313: Some implementations may treat certain names specially,
        !           314: although this not part of the standard for now.
        !           315: The current implementation reserves the names
        !           316: .CW OUT
        !           317: and
        !           318: .CW IN
        !           319: to mean standard output and input.
        !           320: .PP
        !           321: For
        !           322: .I picopen_w ,
        !           323: .I type
        !           324: is the value of the
        !           325: .CW TYPE
        !           326: attribute (e.g., 
        !           327: .CW dump ,
        !           328: .CW runcode ,
        !           329: etc.)
        !           330: .PP
        !           331: .I X0
        !           332: and
        !           333: .I y0
        !           334: are the coordinates of the upper left corner of the image.
        !           335: .I Width
        !           336: and
        !           337: .I height
        !           338: are the size of the image.
        !           339: .I Chan
        !           340: is a string (e.g.
        !           341: .CW rgb ,
        !           342: or
        !           343: .CW m ,
        !           344: or
        !           345: .CW rgbaz... )
        !           346: giving the
        !           347: value of the
        !           348: .CW CHAN
        !           349: attribute and, by implication,
        !           350: .CW NCHAN ,
        !           351: which is always the string length of
        !           352: .I chan.
        !           353: .PP
        !           354: If nonzero,
        !           355: .I argv
        !           356: is the second
        !           357: argument of
        !           358: .I main .
        !           359: This passes information to the picture file routines
        !           360: that allow them to construct the
        !           361: .CW COMMAND
        !           362: attributes that maintain history
        !           363: information.  It is strongly advised that users provide this pointer so
        !           364: proper history can be kept in picture files.
        !           365: .PP
        !           366: If non-zero,
        !           367: .I cmap
        !           368: points at a color-look-up table.
        !           369: .PP
        !           370: Once a picfile has been opened, I/O can be performed by the routines
        !           371: .P1 0
        !           372: int picread(PICFILE *pid, char *buffer);
        !           373: 
        !           374: int picwrite(PICFILE *pid, char *buffer);
        !           375: .P2
        !           376: .I Buffer
        !           377: must be large enough to hold one row of the
        !           378: image (i.e., picture width times number of bytes per pixel).  These
        !           379: routines read or write one row of an image,
        !           380: returning 1 if successful and 0 if error or end-of-file.
        !           381: .PP
        !           382: If an image has
        !           383: .CW TYPE=runcode ,
        !           384: .I picread
        !           385: and
        !           386: .I picwrite
        !           387: will do the run-length
        !           388: decoding and encoding.  If
        !           389: .CW TYPE=bitmap
        !           390: or
        !           391: .CW TYPE=ccitt-g4 ,
        !           392: .I picread
        !           393: will unpack each row of the image into one byte per pixel (with values of 0 or 255), and
        !           394: .I picwrite
        !           395: will pack the pixels back into one bit each by a threshold
        !           396: test (1 if pixel < 128, otherwise 0).
        !           397: .CW TYPE=ccir601
        !           398: files are unpacked and converted into
        !           399: .CW CHAN=rgb
        !           400: format,
        !           401: so that they can be processed by programs designed for conventional
        !           402: color images.
        !           403: .I Picread
        !           404: and
        !           405: .I picwrite
        !           406: do these conversions so that programs
        !           407: need not be greatly concerned with which image
        !           408: type is being used.
        !           409: The idea is to make all encodings look like
        !           410: the simplest,
        !           411: .CW TYPE=dump .
        !           412: .PP
        !           413: A picfile can be closed by
        !           414: .P1 0
        !           415: void picclose(PICFILE *pid);
        !           416: .P2
        !           417: .I Picclose
        !           418: closes the file descriptors and frees allocated memory associated with the picture file.
        !           419: .PP
        !           420: After calling
        !           421: .I picopen_w ,
        !           422: but before the first call to
        !           423: .I picwrite
        !           424: (at which time the header is written out),
        !           425: users may add or change attribute values by calling
        !           426: .P1 0
        !           427: PICFILE *picputprop(PICFILE *pid,
        !           428:        char *name, char *value);
        !           429: .P2
        !           430: .I Picputprop
        !           431: adds the attribute
        !           432: .I name=value
        !           433: to the picture file.  The modified picfile descriptor is returned.
        !           434: .P1 0
        !           435: char *picgetprop(PICFILE *pid, char *name);
        !           436: .P2
        !           437: .I Picgetprop
        !           438: returns the value of the named attribute of a picfile descriptor,
        !           439: or a zero (\fINULL\fP) pointer if absent.
        !           440: .PP
        !           441: Attributes such as
        !           442: .CW COMMAND
        !           443: sometimes appear more than once in a header,
        !           444: as in the example at the start of section 2.
        !           445: .I Picgetprop
        !           446: and
        !           447: .I picputprop
        !           448: treat these as a single attribute-value pair, with newline characters
        !           449: delimiting the sequence of values.
        !           450: .PP
        !           451: There are macros defined in
        !           452: .CW picfile.h
        !           453: to extract commonly-used
        !           454: numeric attributes from picfiles.  Each of the following returns an integer value:
        !           455: .P1 0
        !           456: PIC_NCHAN(pid)    /* value of NCHAN */
        !           457: PIC_WIDTH(pid)    /* picture width */
        !           458: PIC_HEIGHT(pid)   /* picture height */
        !           459: .P2
        !           460: Other attributes should be accessed using
        !           461: .I picgetprop
        !           462: and not by inspecting the
        !           463: .I PICFILE
        !           464: data structure, which may change in the future.
        !           465: .PP
        !           466: The call
        !           467: .P1 0
        !           468: pid2=picopen_w(name, PIC_SAMEARGS(pid1));
        !           469: .P2
        !           470: will create a picture with the same arguments as a previously opened picture.
        !           471: The
        !           472: .I PIC_SAMEARGS
        !           473: macro includes argv in the argument list, so that variable
        !           474: must be defined at the point of call.
        !           475: .PP
        !           476: While not directly related to picture file I/O, the following two routines
        !           477: can assist some application programs which deal with complex pixel definitions.
        !           478: .P1 0
        !           479: void picunpack(PICFILE *pid, char *pixels,
        !           480:    char *format[, void *chan_ptr] ...);
        !           481: 
        !           482: void picpack(PICFILE *pid, char *pixels,
        !           483:    char *format[, void *chan_ptr] ...);
        !           484: .P2
        !           485: .I Picunpack
        !           486: takes
        !           487: an array of pixels (as produced by
        !           488: .I picread )
        !           489: and extracts channels into separate arrays of types specified by
        !           490: .I format .
        !           491: Similarly,
        !           492: .I picpack
        !           493: copies data from various channel arrays and packs
        !           494: them into a single array of pixels (as expected by
        !           495: .I picwrite ).
        !           496: .LP
        !           497: Characters in
        !           498: .I format
        !           499: can be:
        !           500: .IP \fTc\fP
        !           501: read or write a one-byte channel.  The corresponding
        !           502: .I channel_pointer
        !           503: must be of type
        !           504: .I char
        !           505: (or
        !           506: .I "unsigned char" ).
        !           507: .IP \fTs\fP
        !           508: read or write a two-byte channel.  The corresponding
        !           509: .I channel_pointer
        !           510: must be of type
        !           511: .I short .
        !           512: .IP \fTl\fP
        !           513: read or write a four-byte channel.  The corresponding
        !           514: .I channel_pointer
        !           515: must be of type
        !           516: .I long .
        !           517: .IP \fTf\fP
        !           518: read or write a four-byte channel.  The corresponding
        !           519: .I channel_pointer
        !           520: must be of type
        !           521: .I float .
        !           522: .IP \fTd\fP
        !           523: read or write an eight-byte channel.  The corresponding
        !           524: .I channel_pointer
        !           525: must be of type
        !           526: .I double .
        !           527: .IP \fT_\fP
        !           528: underscore indicates a byte in the pixel should be skipped.
        !           529: .PP
        !           530: For example, in a picture with
        !           531: .CW CHAN=rgbz... ,
        !           532: an unpacking of the
        !           533: green channel and the z channel would be done as follows:
        !           534: .P1
        !           535: PICFILE *pid;
        !           536: char *pixels, *green;
        !           537: float *zdepth;
        !           538: picread(pid, pixels);
        !           539: picunpack(pid, pixels, "_c_f",
        !           540:        green, zdepth);
        !           541: .P2
        !           542: By using
        !           543: .I picpack
        !           544: and
        !           545: .I picunpack ,
        !           546: the user also benefits from the standard
        !           547: machine-independent byte ordering that these routines will specify
        !           548: for
        !           549: .I short
        !           550: and
        !           551: .I long
        !           552: type date.  Data of type
        !           553: .I float
        !           554: should also be standardized to use IEEE floating point format, but that
        !           555: is not being done now, so as not to inconvenience users of
        !           556: non-IEEE hardware.
        !           557: .PP
        !           558: Random-access routines such as
        !           559: .I picseek
        !           560: and
        !           561: .I pictell
        !           562: have not been
        !           563: included in order to encourage the development of
        !           564: .UX -style
        !           565: tool programs which can be combined with pipes.  For example,
        !           566: using currently existing tools, a picture file can be resampled
        !           567: to 320\(mu256 as follows:
        !           568: .P1
        !           569: resample 320 pfile1 OUT |
        !           570:        transpose IN OUT |
        !           571:        resample 256 IN OUT |
        !           572:        transpose IN pfile2
        !           573: .P2
        !           574: .NH
        !           575: Example Program
        !           576: .PP
        !           577: Figure 2 shows a complete sample program.
        !           578: .1C
        !           579: .KF
        !           580: .P1 0
        !           581:                /* reflect a picture about horizontal median */
        !           582:                #include <picfile.h>
        !           583:                
        !           584:                main(int argc, char *argv[])
        !           585:                {
        !           586:                        PICFILE *in, *out;
        !           587:                        register char *left, *right, channel;
        !           588:                        char *buffer, *malloc();
        !           589:                        int i;
        !           590:                
        !           591:                        if (argc != 3)
        !           592:                                usage("reflect infile outfile");
        !           593:                        in = picopen_r(argv[1]);
        !           594:                        if (in == 0) {
        !           595:                                perror(argv[1]);
        !           596:                                exit(1);
        !           597:                        }
        !           598:                        out = picopen_w(argv[2], PIC_SAMEARGS(in));
        !           599:                        if (out == 0) {
        !           600:                                perror(argv[2]);
        !           601:                                exit(2);
        !           602:                        }
        !           603:                        buffer = malloc(w*n);
        !           604:                        while (picread(in, buffer)) {
        !           605:                                left = buffer;
        !           606:                                right = buffer + n*(w - 1);
        !           607:                                while (left < right) {
        !           608:                                        for (i = 0; i < n; i++) {
        !           609:                                                channel = *left;
        !           610:                                                *left++ = *right;
        !           611:                                                *right++ = channel;
        !           612:                                        }
        !           613:                                        right -= n + n;
        !           614:                                }
        !           615:                                picwrite(out, buffer);
        !           616:                        }
        !           617:                        exit(0);
        !           618:                }
        !           619: .P2
        !           620: .sp
        !           621: .ce
        !           622: Figure 2
        !           623: .KE
        !           624: .2C
        !           625: .NH
        !           626: Acknowledgements
        !           627: .PP
        !           628: We would like to thank John Amanatides, Jon Helfman and Bob Safranek for
        !           629: there comments and experiences with this picture format.
        !           630: .PP
        !           631: The highly complex CCITT FAX format was implemented by Henry Baird.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.