|
|
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.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.