tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 2083


PNG (Portable Network Graphics) Specification Version 1.0

Part 4 of 4, p. 69 to 102
Prev RFC Part


prevText      Top      Up      ToC       Page 69 
12. Appendix: Rationale

   (This appendix is not part of the formal PNG specification.)

   This appendix gives the reasoning behind some of the design decisions
   in PNG.  Many of these decisions were the subject of considerable
   debate.  The authors freely admit that another group might have made
   different decisions; however, we believe that our choices are
   defensible and consistent.

   12.1. Why a new file format?

      Does the world really need yet another graphics format?  We
      believe so.  GIF is no longer freely usable, but no other commonly
      used format can directly replace it, as is discussed in more
      detail below.  We might have used an adaptation of an existing
      format, for example GIF with an unpatented compression scheme.
      But this would require new code anyway; it would not be all that
      much easier to implement than a whole new file format.  (PNG is
      designed to be simple to implement, with the exception of the
      compression engine, which would be needed in any case.)  We feel
      that this is an excellent opportunity to design a new format that
      fixes some of the known limitations of GIF.

Top      Up      ToC       Page 70 
   12.2. Why these features?

      The features chosen for PNG are intended to address the needs of
      applications that previously used the special strengths of GIF.
      In particular, GIF is well adapted for online communications
      because of its streamability and progressive display capability.
      PNG shares those attributes.

      We have also addressed some of the widely known shortcomings of
      GIF.  In particular, PNG supports truecolor images.  We know of no
      widely used image format that losslessly compresses truecolor
      images as effectively as PNG does.  We hope that PNG will make use
      of truecolor images more practical and widespread.

      Some form of transparency control is desirable for applications in
      which images are displayed against a background or together with
      other images.  GIF provided a simple transparent-color
      specification for this purpose.  PNG supports a full alpha channel
      as well as transparent-color specifications.  This allows both
      highly flexible transparency and compression efficiency.

      Robustness against transmission errors has been an important
      consideration.  For example, images transferred across Internet
      are often mistakenly processed as text, leading to file
      corruption.  PNG is designed so that such errors can be detected
      quickly and reliably.

      PNG has been expressly designed not to be completely dependent on
      a single compression technique. Although deflate/inflate
      compression is mentioned in this document, PNG would still exist
      without it.

   12.3. Why not these features?

      Some features have been deliberately omitted from PNG.  These
      choices were made to simplify implementation of PNG, promote
      portability and interchangeability, and make the format as simple
      and foolproof as possible for users.  In particular:

Top      Up      ToC       Page 71 
          * There is no uncompressed variant of PNG.  It is possible to
            store uncompressed data by using only uncompressed deflate
            blocks (a feature normally used to guarantee that deflate
            does not make incompressible data much larger).  However,
            PNG software must support full deflate/inflate; any software
            that does not is not compliant with the PNG standard. The
            two most important features of PNG---portability and
            compression---are absolute requirements for online
            applications, and users demand them. Failure to support full
            deflate/inflate compromises both of these objectives.
          * There is no lossy compression in PNG.  Existing formats such
            as JFIF already handle lossy compression well.  Furthermore,
            available lossy compression methods (e.g., JPEG) are far
            from foolproof --- a poor choice of quality level can ruin
            an image.  To avoid user confusion and unintentional loss of
            information, we feel it is best to keep lossy and lossless
            formats strictly separate.  Also, lossy compression is
            complex to implement.  Adding JPEG support to a PNG decoder
            might increase its size by an order of magnitude.  This
            would certainly cause some decoders to omit support for the
            feature, which would destroy our goal of interchangeability.
          * There is no support for CMYK or other unusual color spaces.
            Again, this is in the name of promoting portability.  CMYK,
            in particular, is far too device-dependent to be useful as a
            portable image representation.
          * There is no standard chunk for thumbnail views of images.
            In discussions with software vendors who use thumbnails in
            their products, it has become clear that most would not use
            a "standard" thumbnail chunk.  For one thing, every vendor
            has a different idea of what the dimensions and
            characteristics of a thumbnail ought to be.  Also, some
            vendors keep thumbnails in separate files to accommodate
            varied image formats; they are not going to stop doing that
            simply because of a thumbnail chunk in one new format.
            Proprietary chunks containing vendor-specific thumbnails
            appear to be more practical than a common thumbnail format.

      It is worth noting that private extensions to PNG could easily add
      these features.  We will not, however, include them as part of the
      basic PNG standard.

Top      Up      ToC       Page 72 
      PNG also does not support multiple images in one file.  This
      restriction is a reflection of the reality that many applications
      do not need and will not support multiple images per file.  In any
      case, single images are a fundamentally different sort of object
      from sequences of images.  Rather than make false promises of
      interchangeability, we have drawn a clear distinction between
      single-image and multi-image formats.  PNG is a single-image
      format.  (But see Multiple-image extension, Section 8.4.)

   12.4. Why not use format X?

      Numerous existing formats were considered before deciding to
      develop PNG.  None could meet the requirements we felt were
      important for PNG.

      GIF is no longer suitable as a universal standard because of legal
      entanglements.  Although just replacing GIF's compression method
      would avoid that problem, GIF does not support truecolor images,
      alpha channels, or gamma correction.  The spec has more subtle
      problems too.  Only a small subset of the GIF89 spec is actually
      portable across a variety of implementations, but there is no
      codification of the most portable part of the spec.

      TIFF is far too complex to meet our goals of simplicity and
      interchangeability.  Defining a TIFF subset would meet that
      objection, but would frustrate users making the reasonable
      assumption that a file saved as TIFF from their existing software
      would load into a program supporting our flavor of TIFF.
      Furthermore, TIFF is not designed for stream processing, has no
      provision for progressive display, and does not currently provide
      any good, legally unencumbered, lossless compression method.

      IFF has also been suggested, but is not suitable in detail:
      available image representations are too machine-specific or not
      adequately compressed.  The overall chunk structure of IFF is a
      useful concept that PNG has liberally borrowed from, but we did
      not attempt to be bit-for-bit compatible with IFF chunk structure.
      Again this is due to detailed issues, notably the fact that IFF
      FORMs are not designed to be serially writable.

      Lossless JPEG is not suitable because it does not provide for the
      storage of indexed-color images.  Furthermore, its lossless
      truecolor compression is often inferior to that of PNG.

Top      Up      ToC       Page 73 
   12.5. Byte order

      It has been asked why PNG uses network byte order.  We have
      selected one byte ordering and used it consistently. Which order
      in particular is of little relevance, but network byte order has
      the advantage that routines to convert to and from it are already
      available on any platform that supports TCP/IP networking,
      including all PC platforms.  The functions are trivial and will be
      included in the reference implementation.

   12.6. Interlacing

      PNG's two-dimensional interlacing scheme is more complex to
      implement than GIF's line-wise interlacing.  It also costs a
      little more in file size.  However, it yields an initial image
      eight times faster than GIF (the first pass transmits only 1/64th
      of the pixels, compared to 1/8th for GIF).  Although this initial
      image is coarse, it is useful in many situations.  For example, if
      the image is a World Wide Web imagemap that the user has seen
      before, PNG's first pass is often enough to determine where to
      click.  The PNG scheme also looks better than GIF's, because
      horizontal and vertical resolution never differ by more than a
      factor of two; this avoids the odd "stretched" look seen when
      interlaced GIFs are filled in by replicating scanlines.
      Preliminary results show that small text in an interlaced PNG
      image is typically readable about twice as fast as in an
      equivalent GIF, i.e., after PNG's fifth pass or 25% of the image
      data, instead of after GIF's third pass or 50%.  This is again due
      to PNG's more balanced increase in resolution.

   12.7. Why gamma?

      It might seem natural to standardize on storing sample values that
      are linearly proportional to light intensity (that is, have gamma
      of 1.0).  But in fact, it is common for images to have a gamma of
      less than 1.  There are three good reasons for this:

          * For reasons detailed in Gamma Tutorial (Chapter 13), all
            video cameras apply a "gamma correction" function to the
            intensity information.  This causes the video signal to have
            a gamma of about 0.5 relative to the light intensity in the
            original scene.  Thus, images obtained by frame-grabbing
            video already have a gamma of about 0.5.
          * The human eye has a nonlinear response to intensity, so
            linear encoding of samples either wastes sample codes in
            bright areas of the image, or provides too few sample codes
            to avoid banding artifacts in dark areas of the image, or
            both.  At least 12 bits per sample are needed to avoid

Top      Up      ToC       Page 74 
            visible artifacts in linear encoding with a 100:1 image
            intensity range.  An image gamma in the range 0.3 to 0.5
            allocates sample values in a way that roughly corresponds to
            the eye's response, so that 8 bits/sample are enough to
            avoid artifacts caused by insufficient sample precision in
            almost all images.  This makes "gamma encoding" a much
            better way of storing digital images than the simpler linear
          * Many images are created on PCs or workstations with no gamma
            correction hardware and no software willing to provide gamma
            correction either.  In these cases, the images have had
            their lighting and color chosen to look best on this
            platform --- they can be thought of as having "manual" gamma
            correction built in.  To see what the image author intended,
            it is necessary to treat such images as having a file_gamma
            value in the range 0.4-0.6, depending on the room lighting
            level that the author was working in.

      In practice, image gamma values around 1.0 and around 0.5 are both
      widely found.  Older image standards such as GIF often do not
      account for this fact.  The JFIF standard specifies that images in
      that format should use linear samples, but many JFIF images found
      on the Internet actually have a gamma somewhere near 0.4 or 0.5.
      The variety of images found and the variety of systems that people
      display them on have led to widespread problems with images
      appearing "too dark" or "too light".

      PNG expects viewers to compensate for image gamma at the time that
      the image is displayed. Another possible approach is to expect
      encoders to convert all images to a uniform gamma at encoding
      time. While that method would speed viewers slightly, it has
      fundamental flaws:

          * Gamma correction is inherently lossy due to quantization and
            roundoff error.  Requiring conversion at encoding time thus
            causes irreversible loss. Since PNG is intended to be a
            lossless storage format, this is undesirable; we should
            store unmodified source data.
          * The encoder might not know the source gamma value. If the
            decoder does gamma correction at viewing time, it can adjust
            the gamma (change the displayed brightness) in response to
            feedback from a human user. The encoder has no such
          * Whatever "standard" gamma we settled on would be wrong for
            some displays. Hence viewers would still need gamma
            correction capability.

Top      Up      ToC       Page 75 
      Since there will always be images with no gamma or an incorrect
      recorded gamma, good viewers will need to incorporate gamma
      adjustment code anyway. Gamma correction at viewing time is thus
      the right way to go.

      See Gamma Tutorial (Chapter 13) for more information.

   12.8. Non-premultiplied alpha

      PNG uses "unassociated" or "non-premultiplied" alpha so that
      images with separate transparency masks can be stored losslessly.
      Another common technique, "premultiplied alpha", stores pixel
      values premultiplied by the alpha fraction; in effect, the image
      is already composited against a black background.  Any image data
      hidden by the transparency mask is irretrievably lost by that
      method, since multiplying by a zero alpha value always produces

      Some image rendering techniques generate images with premultiplied
      alpha (the alpha value actually represents how much of the pixel
      is covered by the image).  This representation can be converted to
      PNG by dividing the sample values by alpha, except where alpha is
      zero.  The result will look good if displayed by a viewer that
      handles alpha properly, but will not look very good if the viewer
      ignores the alpha channel.

      Although each form of alpha storage has its advantages, we did not
      want to require all PNG viewers to handle both forms.  We
      standardized on non-premultiplied alpha as being the lossless and
      more general case.

   12.9. Filtering

      PNG includes filtering capability because filtering can
      significantly reduce the compressed size of truecolor and
      grayscale images.  Filtering is also sometimes of value on
      indexed-color images, although this is less common.

      The filter algorithms are defined to operate on bytes, rather than
      pixels; this gains simplicity and speed with very little cost in
      compression performance.  Tests have shown that filtering is
      usually ineffective for images with fewer than 8 bits per sample,
      so providing pixelwise filtering for such images would be
      pointless.  For 16 bit/sample data, bytewise filtering is nearly
      as effective as pixelwise filtering, because MSBs are predicted
      from adjacent MSBs, and LSBs are predicted from adjacent LSBs.

Top      Up      ToC       Page 76 
      The encoder is allowed to change filters for each new scanline.
      This creates no additional complexity for decoders, since a
      decoder is required to contain defiltering logic for every filter
      type anyway.  The only cost is an extra byte per scanline in the
      pre-compression datastream.  Our tests showed that when the same
      filter is selected for all scanlines, this extra byte compresses
      away to almost nothing, so there is little storage cost compared
      to a fixed filter specified for the whole image.  And the
      potential benefits of adaptive filtering are too great to ignore.
      Even with the simplistic filter-choice heuristics so far
      discovered, adaptive filtering usually outperforms fixed filters.
      In particular, an adaptive filter can change behavior for
      successive passes of an interlaced image; a fixed filter cannot.

   12.10. Text strings

      Most graphics file formats include the ability to store some
      textual information along with the image.  But many applications
      need more than that: they want to be able to store several
      identifiable pieces of text.  For example, a database using PNG
      files to store medical X-rays would likely want to include
      patient's name, doctor's name, etc.  A simple way to do this in
      PNG would be to invent new private chunks holding text.  The
      disadvantage of such an approach is that other applications would
      have no idea what was in those chunks, and would simply ignore
      them.  Instead, we recommend that textual information be stored in
      standard tEXt chunks with suitable keywords.  Use of tEXt tells
      any PNG viewer that the chunk contains text that might be of
      interest to a human user.  Thus, a person looking at the file with
      another viewer will still be able to see the text, and even
      understand what it is if the keywords are reasonably self-
      explanatory.  (To this end, we recommend spelled-out keywords, not
      abbreviations that will be hard for a person to understand.
      Saving a few bytes on a keyword is false economy.)

      The ISO 8859-1 (Latin-1) character set was chosen as a compromise
      between functionality and portability.  Some platforms cannot
      display anything more than 7-bit ASCII characters, while others
      can handle characters beyond the Latin-1 set.  We felt that
      Latin-1 represents a widely useful and reasonably portable
      character set.  Latin-1 is a direct subset of character sets
      commonly used on popular platforms such as Microsoft Windows and X
      Windows.  It can also be handled on Macintosh systems with a
      simple remapping of characters.

      There is presently no provision for text employing character sets
      other than Latin-1. We recognize that the need for other character
      sets will increase.  However, PNG already requires that

Top      Up      ToC       Page 77 
      programmers implement a number of new and unfamiliar features, and
      text representation is not PNG's primary purpose. Since PNG
      provides for the creation and public registration of new ancillary
      chunks of general interest, we expect that text chunks for other
      character sets, such as Unicode, eventually will be registered and
      increase gradually in popularity.

   12.11. PNG file signature

      The first eight bytes of a PNG file always contain the following

         (decimal)              137  80  78  71  13  10  26  10
         (hexadecimal)           89  50  4e  47  0d  0a  1a  0a
         (ASCII C notation)    \211   P   N   G  \r  \n \032 \n

      This signature both identifies the file as a PNG file and provides
      for immediate detection of common file-transfer problems.  The
      first two bytes distinguish PNG files on systems that expect the
      first two bytes to identify the file type uniquely.  The first
      byte is chosen as a non-ASCII value to reduce the probability that
      a text file may be misrecognized as a PNG file; also, it catches
      bad file transfers that clear bit 7.  Bytes two through four name
      the format.  The CR-LF sequence catches bad file transfers that
      alter newline sequences.  The control-Z character stops file
      display under MS-DOS.  The final line feed checks for the inverse
      of the CR-LF translation problem.

      A decoder may further verify that the next eight bytes contain an
      IHDR chunk header with the correct chunk length; this will catch
      bad transfers that drop or alter null (zero) bytes.

      Note that there is no version number in the signature, nor indeed
      anywhere in the file.  This is intentional: the chunk mechanism
      provides a better, more flexible way to handle format extensions,
      as explained in Chunk naming conventions (Section 12.13).

   12.12. Chunk layout

      The chunk design allows decoders to skip unrecognized or
      uninteresting chunks: it is simply necessary to skip the
      appropriate number of bytes, as determined from the length field.

      Limiting chunk length to (2^31)-1 bytes avoids possible problems
      for implementations that cannot conveniently handle 4-byte
      unsigned values.  In practice, chunks will usually be much shorter
      than that anyway.

Top      Up      ToC       Page 78 
      A separate CRC is provided for each chunk in order to detect
      badly-transferred images as quickly as possible.  In particular,
      critical data such as the image dimensions can be validated before
      being used.

      The chunk length is excluded from the CRC so that the CRC can be
      calculated as the data is generated; this avoids a second pass
      over the data in cases where the chunk length is not known in
      advance.  Excluding the length from the CRC does not create any
      extra risk of failing to discover file corruption, since if the
      length is wrong, the CRC check will fail: the CRC will be computed
      on the wrong set of bytes and then be tested against the wrong
      value from the file.

   12.13. Chunk naming conventions

      The chunk naming conventions allow safe, flexible extension of the
      PNG format.  This mechanism is much better than a format version
      number, because it works on a feature-by-feature basis rather than
      being an overall indicator.  Decoders can process newer files if
      and only if the files use no unknown critical features (as
      indicated by finding unknown critical chunks).  Unknown ancillary
      chunks can be safely ignored.  We decided against having an
      overall format version number because experience has shown that
      format version numbers hurt portability as much as they help.
      Version numbers tend to be set unnecessarily high, leading to
      older decoders rejecting files that they could have processed
      (this was a serious problem for several years after the GIF89 spec
      came out, for example).  Furthermore, private extensions can be
      made either critical or ancillary, and standard decoders should
      react appropriately; overall version numbers are no help for
      private extensions.

      A hypothetical chunk for vector graphics would be a critical
      chunk, since if ignored, important parts of the intended image
      would be missing.  A chunk carrying the Mandelbrot set coordinates
      for a fractal image would be ancillary, since other applications
      could display the image without understanding what the image
      represents.  In general, a chunk type should be made critical only
      if it is impossible to display a reasonable representation of the
      intended image without interpreting that chunk.

Top      Up      ToC       Page 79 
      The public/private property bit ensures that any newly defined
      public chunk type name cannot conflict with proprietary chunks
      that could be in use somewhere.  However, this does not protect
      users of private chunk names from the possibility that someone
      else may use the same chunk name for a different purpose.  It is a
      good idea to put additional identifying information at the start
      of the data for any private chunk type.

      When a PNG file is modified, certain ancillary chunks may need to
      be changed to reflect changes in other chunks. For example, a
      histogram chunk needs to be changed if the image data changes.  If
      the file editor does not recognize histogram chunks, copying them
      blindly to a new output file is incorrect; such chunks should be
      dropped.  The safe/unsafe property bit allows ancillary chunks to
      be marked appropriately.

      Not all possible modification scenarios are covered by the
      safe/unsafe semantics.  In particular, chunks that are dependent
      on the total file contents are not supported.  (An example of such
      a chunk is an index of IDAT chunk locations within the file:
      adding a comment chunk would inadvertently break the index.)
      Definition of such chunks is discouraged.  If absolutely necessary
      for a particular application, such chunks can be made critical
      chunks, with consequent loss of portability to other applications.
      In general, ancillary chunks can depend on critical chunks but not
      on other ancillary chunks.  It is expected that mutually dependent
      information should be put into a single chunk.

      In some situations it may be unavoidable to make one ancillary
      chunk dependent on another.  Although the chunk property bits are
      insufficient to represent this case, a simple solution is
      available: in the dependent chunk, record the CRC of the chunk
      depended on.  It can then be determined whether that chunk has
      been changed by some other program.

      The same technique can be useful for other purposes.  For example,
      if a program relies on the palette being in a particular order, it
      can store a private chunk containing the CRC of the PLTE chunk.
      If this value matches when the file is again read in, then it
      provides high confidence that the palette has not been tampered
      with.  Note that it is not necessary to mark the private chunk
      unsafe-to-copy when this technique is used; thus, such a private
      chunk can survive other editing of the file.

Top      Up      ToC       Page 80 
   12.14. Palette histograms

      A viewer may not be able to provide as many colors as are listed
      in the image's palette.  (For example, some colors could be
      reserved by a window system.)  To produce the best results in this
      situation, it is helpful to have information about the frequency
      with which each palette index actually appears, in order to choose
      the best palette for dithering or to drop the least-used colors.
      Since images are often created once and viewed many times, it
      makes sense to calculate this information in the encoder, although
      it is not mandatory for the encoder to provide it.

      Other image formats have usually addressed this problem by
      specifying that the palette entries should appear in order of
      frequency of use.  That is an inferior solution, because it
      doesn't give the viewer nearly as much information: the viewer
      can't determine how much damage will be done by dropping the last
      few colors.  Nor does a sorted palette give enough information to
      choose a target palette for dithering, in the case that the viewer
      needs to reduce the number of colors substantially.  A palette
      histogram provides the information needed to choose such a target
      palette without making a pass over the image data.

Top      Up      ToC       Page 81 
13. Appendix: Gamma Tutorial

   (This appendix is not part of the formal PNG specification.)

   It would be convenient for graphics programmers if all of the
   components of an imaging system were linear.  The voltage coming from
   an electronic camera would be directly proportional to the intensity
   (power) of light in the scene, the light emitted by a CRT would be
   directly proportional to its input voltage, and so on.  However,
   real-world devices do not behave in this way.  All CRT displays,
   almost all photographic film, and many electronic cameras have
   nonlinear signal-to-light-intensity or intensity-to-signal

   Fortunately, all of these nonlinear devices have a transfer function
   that is approximated fairly well by a single type of mathematical
   function: a power function.  This power function has the general

      output = input ^ gamma

   where ^ denotes exponentiation, and "gamma" (often printed using the
   Greek letter gamma, thus the name) is simply the exponent of the
   power function.

   By convention, "input" and "output" are both scaled to the range
   0..1, with 0 representing black and 1 representing maximum white (or
   red, etc).  Normalized in this way, the power function is completely
   described by a single number, the exponent "gamma".

   So, given a particular device, we can measure its output as a
   function of its input, fit a power function to this measured transfer
   function, extract the exponent, and call it gamma.  We often say
   "this device has a gamma of 2.5" as a shorthand for "this device has
   a power-law response with an exponent of 2.5".  We can also talk
   about the gamma of a mathematical transform, or of a lookup table in
   a frame buffer, so long as the input and output of the thing are
   related by the power-law expression above.

   How do gammas combine?

      Real imaging systems will have several components, and more than
      one of these can be nonlinear.  If all of the components have
      transfer characteristics that are power functions, then the
      transfer function of the entire system is also a power function.
      The exponent (gamma) of the whole system's transfer function is
      just the product of all of the individual exponents (gammas) of
      the separate stages in the system.

Top      Up      ToC       Page 82 
      Also, stages that are linear pose no problem, since a power
      function with an exponent of 1.0 is really a linear function.  So
      a linear transfer function is just a special case of a power
      function, with a gamma of 1.0.

      Thus, as long as our imaging system contains only stages with
      linear and power-law transfer functions, we can meaningfully talk
      about the gamma of the entire system.  This is indeed the case
      with most real imaging systems.

   What should overall gamma be?

      If the overall gamma of an imaging system is 1.0, its output is
      linearly proportional to its input.  This means that the ratio
      between the intensities of any two areas in the reproduced image
      will be the same as it was in the original scene.  It might seem
      that this should always be the goal of an imaging system: to
      accurately reproduce the tones of the original scene.  Alas, that
      is not the case.

      When the reproduced image is to be viewed in "bright surround"
      conditions, where other white objects nearby in the room have
      about the same brightness as white in the image, then an overall
      gamma of 1.0 does indeed give real-looking reproduction of a
      natural scene.  Photographic prints viewed under room light and
      computer displays in bright room light are typical "bright
      surround" viewing conditions.

      However, sometimes images are intended to be viewed in "dark
      surround" conditions, where the room is substantially black except
      for the image.  This is typical of the way movies and slides
      (transparencies) are viewed by projection.  Under these
      circumstances, an accurate reproduction of the original scene
      results in an image that human viewers judge as "flat" and lacking
      in contrast.  It turns out that the projected image needs to have
      a gamma of about 1.5 relative to the original scene for viewers to
      judge it "natural".  Thus, slide film is designed to have a gamma
      of about 1.5, not 1.0.

      There is also an intermediate condition called "dim surround",
      where the rest of the room is still visible to the viewer, but is
      noticeably darker than the reproduced image itself.  This is
      typical of television viewing, at least in the evening, as well as
      subdued-light computer work areas.  In dim surround conditions,
      the reproduced image needs to have a gamma of about 1.25 relative
      to the original scene in order to look natural.

Top      Up      ToC       Page 83 
      The requirement for boosted contrast (gamma) in dark surround
      conditions is due to the way the human visual system works, and
      applies equally well to computer monitors.  Thus, a PNG viewer
      trying to achieve the maximum realism for the images it displays
      really needs to know what the room lighting conditions are, and
      adjust the gamma of the displayed image accordingly.

      If asking the user about room lighting conditions is inappropriate
      or too difficult, just assume that the overall gamma
      (viewing_gamma as defined below) should be 1.0 or 1.25.  That's
      all that most systems that implement gamma correction do.

   What is a CRT's gamma?

      All CRT displays have a power-law transfer characteristic with a
      gamma of about 2.5.  This is due to the physical processes
      involved in controlling the electron beam in the electron gun, and
      has nothing to do with the phosphor.

      An exception to this rule is fancy "calibrated" CRTs that have
      internal electronics to alter their transfer function.  If you
      have one of these, you probably should believe what the
      manufacturer tells you its gamma is.  But in all other cases,
      assuming 2.5 is likely to be pretty accurate.

      There are various images around that purport to measure gamma,
      usually by comparing the intensity of an area containing
      alternating white and black with a series of areas of continuous
      gray of different intensity.  These are usually not reliable.
      Test images that use a "checkerboard" pattern of black and white
      are the worst, because a single white pixel will be reproduced
      considerably darker than a large area of white.  An image that
      uses alternating black and white horizontal lines (such as the
      "gamma.png" test image at is much
      better, but even it may be inaccurate at high "picture" settings
      on some CRTs.

      If you have a good photometer, you can measure the actual light
      output of a CRT as a function of input voltage and fit a power
      function to the measurements.  However, note that this procedure
      is very sensitive to the CRT's black level adjustment, somewhat
      sensitive to its picture adjustment, and also affected by ambient
      light.  Furthermore, CRTs spread some light from bright areas of
      an image into nearby darker areas; a single bright spot against a
      black background may be seen to have a "halo".  Your measuring
      technique will need to minimize the effects of this.

Top      Up      ToC       Page 84 
      Because of the difficulty of measuring gamma, using either test
      images or measuring equipment, you're usually better off just
      assuming gamma is 2.5 rather than trying to measure it.

   What is gamma correction?

      A CRT has a gamma of 2.5, and we can't change that.  To get an
      overall gamma of 1.0 (or somewhere near that) for an imaging
      system, we need to have at least one other component of the "image
      pipeline" that is nonlinear.  If, in fact, there is only one
      nonlinear stage in addition to the CRT, then it's traditional to
      say that the CRT has a certain gamma, and that the other nonlinear
      stage provides "gamma correction" to compensate for the CRT.
      However, exactly where the "correction" is done depends on

      In all broadcast video systems, gamma correction is done in the
      camera.  This choice was made in the days when television
      electronics were all analog, and a good gamma-correction circuit
      was expensive to build.  The original NTSC video standard required
      cameras to have a transfer function with a gamma of 1/2.2, or
      about 0.45.  Recently, a more complex two-part transfer function
      has been adopted [SMPTE-170M], but its behavior can be well
      approximated by a power function with a gamma of 0.5.  When the
      resulting image is displayed on a CRT with a gamma of 2.5, the
      image on screen ends up with a gamma of about 1.25 relative to the
      original scene, which is appropriate for "dim surround" viewing.

      These days, video signals are often digitized and stored in
      computer frame buffers.  This works fine, but remember that gamma
      correction is "built into" the video signal, and so the digitized
      video has a gamma of about 0.5 relative to the original scene.

      Computer rendering programs often produce linear samples.  To
      display these correctly, intensity on the CRT needs to be directly
      proportional to the sample values in the frame buffer.  This can
      be done with a special hardware lookup table between the frame
      buffer and the CRT hardware.  The lookup table (often called LUT)
      is loaded with a mapping that implements a power function with a
      gamma of 0.4, thus providing "gamma correction" for the CRT gamma.

      Thus, gamma correction sometimes happens before the frame buffer,
      sometimes after.  As long as images created in a particular
      environment are always displayed in that environment, everything
      is fine.  But when people try to exchange images, differences in
      gamma correction conventions often result in images that seem far
      too bright and washed out, or far too dark and contrasty.

Top      Up      ToC       Page 85 
   Gamma-encoded samples are good

      So, is it better to do gamma correction before or after the frame

      In an ideal world, sample values would be stored in floating
      point, there would be lots of precision, and it wouldn't really
      matter much.  But in reality, we're always trying to store images
      in as few bits as we can.

      If we decide to use samples that are linearly proportional to
      intensity, and do the gamma correction in the frame buffer LUT, it
      turns out that we need to use at least 12 bits for each of red,
      green, and blue to have enough precision in intensity.  With any
      less than that, we will sometimes see "contour bands" or "Mach
      bands" in the darker areas of the image, where two adjacent sample
      values are still far enough apart in intensity for the difference
      to be visible.

      However, through an interesting coincidence, the human eye's
      subjective perception of brightness is related to the physical
      stimulation of light intensity in a manner that is very much like
      the power function used for gamma correction.  If we apply gamma
      correction to measured (or calculated) light intensity before
      quantizing to an integer for storage in a frame buffer, we can get
      away with using many fewer bits to store the image.  In fact, 8
      bits per color is almost always sufficient to avoid contouring
      artifacts.  This is because, since gamma correction is so closely
      related to human perception, we are assigning our 256 available
      sample codes to intensity values in a manner that approximates how
      visible those intensity changes are to the eye.  Compared to a
      linear-sample image, we allocate fewer sample values to brighter
      parts of the tonal range and more sample values to the darker
      portions of the tonal range.

      Thus, for the same apparent image quality, images using gamma-
      encoded sample values need only about two-thirds as many bits of
      storage as images using linear samples.

Top      Up      ToC       Page 86 
   General gamma handling

      When more than two nonlinear transfer functions are involved in
      the image pipeline, the term "gamma correction" becomes too vague.
      If we consider a pipeline that involves capturing (or calculating)
      an image, storing it in an image file, reading the file, and
      displaying the image on some sort of display screen, there are at
      least 5 places in the pipeline that could have nonlinear transfer
      functions.  Let's give each a specific name for their
      characteristic gamma:

         the characteristic of the image sensor

         the gamma of any transformation performed by the software
         writing the image file

         the gamma of any transformation performed by the software
         reading the image file

         the gamma of the frame buffer LUT, if present

         the gamma of the CRT, generally 2.5

      In addition, let's add a few other names:

         the gamma of the image in the file, relative to the original
         scene.  This is

            file_gamma = camera_gamma * encoding_gamma

         the gamma of the "display system" downstream of the frame
         buffer.  This is

            display_gamma = LUT_gamma * CRT_gamma

         the overall gamma that we want to obtain to produce pleasing
         images --- generally 1.0 to 1.5.

Top      Up      ToC       Page 87 
      The file_gamma value, as defined above, is what goes in the gAMA
      chunk in a PNG file.  If file_gamma is not 1.0, we know that gamma
      correction has been done on the sample values in the file, and we
      could call them "gamma corrected" samples.  However, since there
      can be so many different values of gamma in the image display
      chain, and some of them are not known at the time the image is
      written, the samples are not really being "corrected" for a
      specific display condition.  We are really using a power function
      in the process of encoding an intensity range into a small integer
      field, and so it is more correct to say "gamma encoded" samples
      instead of "gamma corrected" samples.

      When displaying an image file, the image decoding program is
      responsible for making the overall gamma of the system equal to
      the desired viewing_gamma, by selecting the decoding_gamma
      appropriately.  When displaying a PNG file, the gAMA chunk
      provides the file_gamma value.  The display_gamma may be known for
      this machine, or it might be obtained from the system software, or
      the user might have to be asked what it is.  The correct
      viewing_gamma depends on lighting conditions, and that will
      generally have to come from the user.

      Ultimately, you should have

         file_gamma * decoding_gamma * display_gamma = viewing_gamma

   Some specific examples

      In digital video systems, camera_gamma is about 0.5 by declaration
      of the various video standards documents.  CRT_gamma is 2.5 as
      usual, while encoding_gamma, decoding_gamma, and LUT_gamma are all
      1.0.  As a result, viewing_gamma ends up being about 1.25.

      On frame buffers that have hardware gamma correction tables, and
      that are calibrated to display linear samples correctly,
      display_gamma is 1.0.

      Many workstations and X terminals and PC displays lack gamma
      correction lookup tables.  Here, LUT_gamma is always 1.0, so
      display_gamma is 2.5.

Top      Up      ToC       Page 88 
      On the Macintosh, there is a LUT.  By default, it is loaded with a
      table whose gamma is about 0.72, giving a display_gamma (LUT and
      CRT combined) of about 1.8.  Some Macs have a "Gamma" control
      panel that allows gamma to be changed to 1.0, 1.2, 1.4, 1.8, or
      2.2.  These settings load alternate LUTs that are designed to give
      a display_gamma that is equal to the label on the selected button.
      Thus, the "Gamma" control panel setting can be used directly as
      display_gamma in decoder calculations.

      On recent SGI systems, there is a hardware gamma-correction table
      whose contents are controlled by the (privileged) "gamma" program.
      The gamma of the table is actually the reciprocal of the number
      that "gamma" prints, and it does not include the CRT gamma. To
      obtain the display_gamma, you need to find the SGI system gamma
      (either by looking in a file, or asking the user) and then

         display_gamma = 2.5 / SGI_system_gamma

      You will find SGI systems with the system gamma set to 1.0 and 2.2
      (or higher), but the default when machines are shipped is 1.7.

   A note about video gamma

      The original NTSC video standards specified a simple power-law
      camera transfer function with a gamma of 1/2.2 or 0.45.  This is
      not possible to implement exactly in analog hardware because the
      function has infinite slope at x=0, so all cameras deviated to
      some degree from this ideal.  More recently, a new camera transfer
      function that is physically realizable has been accepted as a
      standard [SMPTE-170M].  It is

         Vout = 4.5 * Vin                    if Vin < 0.018
         Vout = 1.099 * (Vin^0.45) - 0.099   if Vin >= 0.018

      where Vin and Vout are measured on a scale of 0 to 1.  Although
      the exponent remains 0.45, the multiplication and subtraction
      change the shape of the transfer function, so it is no longer a
      pure power function.  If you want to perform extremely precise
      calculations on video signals, you should use the expression above
      (or its inverse, as required).

      However, PNG does not provide a way to specify that an image uses
      this exact transfer function; the gAMA chunk always assumes a pure
      power-law function. If we plot the two-part transfer function
      above along with the family of pure power functions, we find that
      a power function with a gamma of about 0.5 to 0.52 (not 0.45) most
      closely approximates the transfer function.  Thus, when writing a

Top      Up      ToC       Page 89 
      PNG file with data obtained from digitizing the output of a modern
      video camera, the gAMA chunk should contain 0.5 or 0.52, not 0.45.
      The remaining difference between the true transfer function and
      the power function is insignificant for almost all purposes.  (In
      fact, the alignment errors in most cameras are likely to be larger
      than the difference between these functions.)  The designers of
      PNG deemed the simplicity and flexibility of a power-law
      definition of gAMA to be more important than being able to
      describe the SMPTE-170M transfer curve exactly.

      The PAL and SECAM video standards specify a power-law camera
      transfer function with a gamma of 1/2.8 or 0.36 --- not the 1/2.2
      of NTSC.  However, this is too low in practice, so real cameras
      are likely to have their gamma set close to NTSC practice.  Just
      guessing 0.45 or 0.5 is likely to give you viewable results, but
      if you want precise values you'll probably have to measure the
      particular camera.

   Further reading

      If you have access to the World Wide Web, read Charles Poynton's
      excellent "Gamma FAQ" [GAMMA-FAQ] for more information about

14. Appendix: Color Tutorial

   (This appendix is not part of the formal PNG specification.)

   About chromaticity

      The cHRM chunk is used, together with the gAMA chunk, to convey
      precise color information so that a PNG image can be displayed or
      printed with better color fidelity than is possible without this
      information.  The preceding chapters state how this information is
      encoded in a PNG image.  This tutorial briefly outlines the
      underlying color theory for those who might not be familiar with

      Note that displaying an image with incorrect gamma will produce
      much larger color errors than failing to use the chromaticity
      data.  First be sure the monitor set-up and gamma correction are
      right, then worry about chromaticity.

   The problem

      The color of an object depends not only on the precise spectrum of
      light emitted or reflected from it, but also on the observer ---
      their species, what else they can see at the same time, even what

Top      Up      ToC       Page 90 
      they have recently looked at!  Furthermore, two very different
      spectra can produce exactly the same color sensation.  Color is
      not an objective property of real-world objects; it is a
      subjective, biological sensation.  However, by making some
      simplifying assumptions (such as: we are talking about human
      vision) it is possible to produce a mathematical model of color
      and thereby obtain good color accuracy.

   Device-dependent color

      Display the same RGB data on three different monitors, side by
      side, and you will get a noticeably different color balance on
      each display.  This is because each monitor emits a slightly
      different shade and intensity of red, green, and blue light.  RGB
      is an example of a device-dependent color model --- the color you
      get depends on the device.  This also means that a particular
      color --- represented as say RGB 87, 146, 116 on one monitor ---
      might have to be specified as RGB 98, 123, 104 on another to
      produce the same color.

   Device-independent color

      A full physical description of a color would require specifying
      the exact spectral power distribution of the light source.
      Fortunately, the human eye and brain are not so sensitive as to
      require exact reproduction of a spectrum.  Mathematical, device-
      independent color models exist that describe fairly well how a
      particular color will be seen by humans.  The most important
      device-independent color model, to which all others can be
      related, was developed by the International Lighting Committee
      (CIE, in French) and is called XYZ.

      In XYZ, X is the sum of a weighted power distribution over the
      whole visible spectrum.  So are Y and Z, each with different
      weights.  Thus any arbitrary spectral power distribution is
      condensed down to just three floating point numbers.  The weights
      were derived from color matching experiments done on human
      subjects in the 1920s.  CIE XYZ has been an International Standard
      since 1931, and it has a number of useful properties:

          * two colors with the same XYZ values will look the same to
          * two colors with different XYZ values will not look the same
          * the Y value represents all the brightness information
          * the XYZ color of any object can be objectively measured

Top      Up      ToC       Page 91 
      Color models based on XYZ have been used for many years by people
      who need accurate control of color --- lighting engineers for film
      and TV, paint and dyestuffs manufacturers, and so on.  They are
      thus proven in industrial use.  Accurate, device-independent color
      started to spread from high-end, specialized areas into the
      mainstream during the late 1980s and early 1990s, and PNG takes
      notice of that trend.

   Calibrated, device-dependent color

      Traditionally, image file formats have used uncalibrated, device-
      dependent color.  If the precise details of the original display
      device are known, it becomes possible to convert the device-
      dependent colors of a particular image to device-independent ones.
      Making simplifying assumptions, such as working with CRTs (which
      are much easier than printers), all we need to know are the XYZ
      values of each primary color and the CRT_gamma.

      So why does PNG not store images in XYZ instead of RGB?  Well, two
      reasons.  First, storing images in XYZ would require more bits of
      precision, which would make the files bigger.  Second, all
      programs would have to convert the image data before viewing it.
      Whether calibrated or not, all variants of RGB are close enough
      that undemanding viewers can get by with simply displaying the
      data without color correction.  By storing calibrated RGB, PNG
      retains compatibility with existing programs that expect RGB data,
      yet provides enough information for conversion to XYZ in
      applications that need precise colors.  Thus, we get the best of
      both worlds.

   What are chromaticity and luminance?

      Chromaticity is an objective measurement of the color of an
      object, leaving aside the brightness information.  Chromaticity
      uses two parameters x and y, which are readily calculated from

         x = X / (X + Y + Z)
         y = Y / (X + Y + Z)

      XYZ colors having the same chromaticity values will appear to have
      the same hue but can vary in absolute brightness.  Notice that x,y
      are dimensionless ratios, so they have the same values no matter
      what units we've used for X,Y,Z.

Top      Up      ToC       Page 92 
      The Y value of an XYZ color is directly proportional to its
      absolute brightness and is called the luminance of the color.  We
      can describe a color either by XYZ coordinates or by chromaticity
      x,y plus luminance Y.  The XYZ form has the advantage that it is
      linearly related to (linear, gamma=1.0) RGB color spaces.

   How are computer monitor colors described?

      The "white point" of a monitor is the chromaticity x,y of the
      monitor's nominal white, that is, the color produced when

      It's customary to specify monitor colors by giving the
      chromaticities of the individual phosphors R, G, and B, plus the
      white point.  The white point allows one to infer the relative
      brightnesses of the three phosphors, which isn't determined by
      their chromaticities alone.

      Note that the absolute brightness of the monitor is not specified.
      For computer graphics work, we generally don't care very much
      about absolute brightness levels.  Instead of dealing with
      absolute XYZ values (in which X,Y,Z are expressed in physical
      units of radiated power, such as candelas per square meter), it is
      convenient to work in "relative XYZ" units, where the monitor's
      nominal white is taken to have a luminance (Y) of 1.0.  Given this
      assumption, it's simple to compute XYZ coordinates for the
      monitor's white, red, green, and blue from their chromaticity

      Why does cHRM use x,y rather than XYZ?  Simply because that is how
      manufacturers print the information in their spec sheets!
      Usually, the first thing a program will do is convert the cHRM
      chromaticities into relative XYZ space.

   What can I do with it?

      If a PNG file has the gAMA and cHRM chunks, the source_RGB values
      can be converted to XYZ.  This lets you:

          * do accurate grayscale conversion (just use the Y component)
          * convert to RGB for your own monitor (to see the original
          * print the image in Level 2 PostScript with better color
            fidelity than a simple RGB to CMYK conversion could provide
          * calculate an optimal color palette
          * pass the image data to a color management system
          * etc.

Top      Up      ToC       Page 93 
   How do I convert from source_RGB to XYZ?

      Make a few simplifying assumptions first, like the monitor really
      is jet black with no input and the guns don't interfere with one
      another.  Then, given that you know the CIE XYZ values for each of
      red, green, and blue for a particular monitor, you put them into a
      matrix m:

                 Xr Xg Xb
            m =  Yr Yg Yb
                 Zr Zg Zb

      Here we assume we are working with linear RGB floating point data
      in the range 0..1.  If the gamma is not 1.0, make it so on the
      floating point data.  Then convert source_RGB to XYZ by matrix

            X     R
            Y = m G
            Z     B

      In other words, X = Xr*R + Xg*G + Xb*B, and similarly for Y and Z.
      You can go the other way too:

            R      X
            G = im Y
            B      Z

      where im is the inverse of the matrix m.

   What is a gamut?

      The gamut of a device is the subset of visible colors which that
      device can display.  (It has nothing to do with gamma.)  The gamut
      of an RGB device can be visualized as a polyhedron in XYZ space;
      the vertices correspond to the device's black, blue, red, green,
      magenta, cyan, yellow and white.

      Different devices have different gamuts, in other words one device
      will be able to display certain colors (usually highly saturated
      ones) that another device cannot.  The gamut of a particular RGB
      device can be determined from its R, G, and B chromaticities and
      white point (the same values given in the cHRM chunk).  The gamut
      of a color printer is more complex and can only be determined by
      measurement.  However, printer gamuts are typically smaller than
      monitor gamuts, meaning that there can be many colors in a
      displayable image that cannot physically be printed.

Top      Up      ToC       Page 94 
      Converting image data from one device to another generally results
      in gamut mismatches --- colors that cannot be represented exactly
      on the destination device.  The process of making the colors fit,
      which can range from a simple clip to elaborate nonlinear scaling
      transformations, is termed gamut mapping.  The aim is to produce a
      reasonable visual representation of the original image.

   Further reading

      References [COLOR-1] through [COLOR-5] provide more detail about
      color theory.

15. Appendix: Sample CRC Code

   The following sample code represents a practical implementation of
   the CRC (Cyclic Redundancy Check) employed in PNG chunks.  (See also
   ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-V42] for a formal

   The sample code is in the ANSI C programming language.  Non C users
   may find it easier to read with these hints:

      Bitwise AND operator.

      Bitwise exclusive-OR operator.  (Caution: elsewhere in this
      document, ^ represents exponentiation.)

      Bitwise right shift operator.  When applied to an unsigned
      quantity, as here, right shift inserts zeroes at the left.

      Logical NOT operator.

      "n++" increments the variable n.

      0x introduces a hexadecimal (base 16) constant.  Suffix L
      indicates a long value (at least 32 bits).

      /* Table of CRCs of all 8-bit messages. */
      unsigned long crc_table[256];

      /* Flag: has the table been computed? Initially false. */
      int crc_table_computed = 0;

Top      Up      ToC       Page 95 
      /* Make the table for a fast CRC. */
      void make_crc_table(void)
        unsigned long c;
        int n, k;
        for (n = 0; n < 256; n++) {
          c = (unsigned long) n;
          for (k = 0; k < 8; k++) {
            if (c & 1)
              c = 0xedb88320L ^ (c >> 1);
              c = c >> 1;
          crc_table[n] = c;
        crc_table_computed = 1;

      /* Update a running CRC with the bytes buf[0..len-1]--the CRC
         should be initialized to all 1's, and the transmitted value
         is the 1's complement of the final running CRC (see the
         crc() routine below)). */

      unsigned long update_crc(unsigned long crc, unsigned char *buf,
                               int len)
        unsigned long c = crc;
        int n;

        if (!crc_table_computed)
        for (n = 0; n < len; n++) {
          c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
        return c;

      /* Return the CRC of the bytes buf[0..len-1]. */
      unsigned long crc(unsigned char *buf, int len)
        return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;

Top      Up      ToC       Page 96 
16. Appendix: Online Resources

   (This appendix is not part of the formal PNG specification.)

   This appendix gives the locations of some Internet resources for PNG
   software developers.  By the nature of the Internet, the list is
   incomplete and subject to change.

   Archive sites

      The latest released versions of this document and related
      information can always be found at the PNG FTP archive site,  The PNG specification is
      available in several formats, including HTML, plain text, and

   Reference implementation and test images

      A reference implementation in portable C is available from the PNG
      FTP archive site,  The
      reference implementation is freely usable in all applications,
      including commercial applications.

      Test images are available from

   Electronic mail

      The maintainers of the PNG specification can be contacted by e-
      mail at or at

   PNG home page

      There is a World Wide Web home page for PNG at  This page is a central location
      for current information about PNG and PNG-related tools.

17. Appendix: Revision History

   (This appendix is not part of the formal PNG specification.)

   The PNG format has been frozen since the Ninth Draft of March 7,
   1995, and all future changes are intended to be backwards compatible.
   The revisions since the Ninth Draft are simply clarifications,
   improvements in presentation, and additions of supporting material.

   On 1 October 1996, the PNG specification was approved as a W3C (World
   Wide Web Consortium) Recommendation.

Top      Up      ToC       Page 97 
   Changes since the Tenth Draft of 5 May, 1995

          * Clarified meaning of a suggested-palette PLTE chunk in a
            truecolor image that uses transparency
          * Clarified exact semantics of sBIT and allowed sample depth
            scaling procedures
          * Clarified status of spaces in tEXt chunk keywords
          * Distinguished private and public extension values in type
            and method fields
          * Added a "Creation Time" tEXt keyword
          * Macintosh representation of PNG specified
          * Added discussion of security issues
          * Added more extensive discussion of gamma and chromaticity
            handling, including tutorial appendixes
          * Clarified terminology, notably sample depth vs. bit depth
          * Added a glossary
          * Editing and reformatting

18. References

      Hall, Roy, Illumination and Color in Computer Generated Imagery.
      Springer-Verlag, New York, 1989.  ISBN 0-387-96774-5.

      Kasson, J., and W. Plouffe, "An Analysis of Selected Computer
      Interchange Color Spaces", ACM Transactions on Graphics, vol 11 no
      4 (1992), pp 373-405.

      Lilley, C., F. Lin, W.T. Hewitt, and T.L.J. Howard, Colour in
      Computer Graphics. CVCP, Sheffield, 1993.  ISBN 1-85889-022-5.
      Also available from

      Stone, M.C., W.B. Cowan, and J.C. Beatty, "Color gamut mapping and
      the printing of digital images", ACM Transactions on Graphics, vol
      7 no 3 (1988), pp 249-292.

      Travis, David, Effective Color Displays --- Theory and Practice.
      Academic Press, London, 1991.  ISBN 0-12-697690-2.

      Poynton, C., "Gamma FAQ".

Top      Up      ToC       Page 98 
      International Organization for Standardization, "Information
      Processing Systems --- Data Communication High-Level Data Link
      Control Procedure --- Frame Structure", IS 3309, October 1984, 3rd

      International Organization for Standardization, "Information
      Processing --- 8-bit Single-Byte Coded Graphic Character Sets ---
      Part 1: Latin Alphabet No. 1", IS 8859-1, 1987.
      Also see sample files at*

      International Telecommunications Union, "Basic Parameter Values
      for the HDTV Standard for the Studio and for International
      Programme Exchange", ITU-R Recommendation BT.709 (formerly CCIR
      Rec. 709), 1990.

      International Telecommunications Union, "Error-correcting
      Procedures for DCEs Using Asynchronous-to-Synchronous Conversion",
      ITU-T Recommendation V.42, 1994, Rev. 1.

      Paeth, A.W., "Image File Compression Made Easy", in Graphics Gems
      II, James Arvo, editor.  Academic Press, San Diego, 1991.  ISBN

      Adobe Systems Incorporated, PostScript Language Reference Manual,
      2nd edition. Addison-Wesley, Reading, 1990.  ISBN 0-201-18127-4.

      PNG Group, "PNG Special-Purpose Public Chunks".  Available in
      several formats from*

      Braden, R., Editor, "Requirements for Internet Hosts ---
      Application and Support", STD 3, RFC 1123, USC/Information
      Sciences Institute, October 1989.

Top      Up      ToC       Page 99 
      Freed, N., and N. Borenstein, "Multipurpose Internet Mail
      Extensions (MIME) Part One: Format of Internet Message Bodies",
      RFC 2045, Innosoft, First Virtual, November 1996.

      Freed, N., Klensin, J., and J. Postel, "Multipurpose Internet Mail
      Extensions (MIME) Part Four: Registration Procedures", RFC 2048,
      Innosoft, MCI, USC/Information Sciences Institute, November 1996.

      Deutsch, P. and J-L. Gailly, "ZLIB Compressed Data Format
      Specification version 3.3", RFC 1950, Aladdin Enterprises, May

      Deutsch, P., "DEFLATE Compressed Data Format Specification version
      1.3", RFC 1951, Aladdin Enterprises, May 1996.

      Society of Motion Picture and Television Engineers, "Television
      --- Composite Analog Video Signal --- NTSC for Studio
      Applications", SMPTE-170M, 1994.

Top      Up      ToC       Page 100 
19. Credits


      Thomas Boutell,

   Contributing Editor

      Tom Lane,


      Authors' names are presented in alphabetical order.

          * Mark Adler,
          * Thomas Boutell,
          * Christian Brunschen,
          * Adam M. Costello,
          * Lee Daniel Crocker,
          * Andreas Dilger,
          * Oliver Fromme,
          * Jean-loup Gailly,
          * Chris Herborth,
          * Alex Jakulin,
          * Neal Kettler,
          * Tom Lane,
          * Alexander Lehmann,
          * Chris Lilley,
          * Dave Martindale,
          * Owen Mortensen,
          * Keith S. Pickens,
          * Robert P. Poole,
          * Glenn Randers-Pehrson, or
          * Greg Roelofs,
          * Willem van Schaik,
          * Guy Schalnat
          * Paul Schmidt,
          * Tim Wegner,
          * Jeremy Wohl,

      The authors wish to acknowledge the contributions of the Portable
      Network Graphics mailing list, the readers of, and
      the members of the World Wide Web Consortium (W3C).

Top      Up      ToC       Page 101 
      The Adam7 interlacing scheme is not patented and it is not the
      intention of the originator of that scheme to patent it. The
      scheme may be freely used by all PNG implementations. The name
      "Adam7" may be freely used to describe interlace method 1 of the
      PNG specification.


      GIF is a service mark of CompuServe Incorporated.  IBM PC is a
      trademark of International Business Machines Corporation.
      Macintosh is a trademark of Apple Computer, Inc.  Microsoft and
      MS-DOS are trademarks of Microsoft Corporation.  PhotoCD is a
      trademark of Eastman Kodak Company.  PostScript and TIFF are
      trademarks of Adobe Systems Incorporated.  SGI is a trademark of
      Silicon Graphics, Inc.  X Window System is a trademark of the
      Massachusetts Institute of Technology.


   Copyright (c) 1996 by: Massachusetts Institute of Technology (MIT)

   This W3C specification is being provided by the copyright holders
   under the following license. By obtaining, using and/or copying this
   specification, you agree that you have read, understood, and will
   comply with the following terms and conditions:

   Permission to use, copy, and distribute this specification for any
   purpose and without fee or royalty is hereby granted, provided that
   the full text of this NOTICE appears on ALL copies of the
   specification or portions thereof, including modifications, that you


Top      Up      ToC       Page 102 
   The name and trademarks of copyright holders may NOT be used in
   advertising or publicity pertaining to the specification without
   specific, written prior permission.  Title to copyright in this
   specification and any associated documentation will at all times
   remain with copyright holders.

Security Considerations

   Security issues are discussed in Security considerations (Section

Author's Address

   Thomas Boutell
   PO Box 20837
   Seattle, WA  98102

   Phone: (206) 329-4969