<?xml version="1.0"?>
<!-- vim: set ts=2 sw=2 expandtab: --> 
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<refentry id="file-format">
  <refmeta>
    <refentrytitle>The VIPS file format</refentrytitle>
    <manvolnum>3</manvolnum>
    <refmiscinfo>VIPS Library</refmiscinfo>
  </refmeta>

  <refnamediv>
    <refname>File format</refname>
    <refpurpose>The VIPS file format</refpurpose>
  </refnamediv>

  <refsect3 id="vips-format">
    <title>Introduction</title>
    <para>
      VIPS has a simple, native file format. It's very fast, there is no image 
      size limit, and it supports 
      arbitrary metadata. Although few other programs can read these images 
      (though recent versions of ImageMagick do have basic support for 
      <code>.vips</code> 
      format), it can be useful as an intermediate format for command-line 
      processing. For example:

<programlisting language="bash">
$ vips invert input.tif t.v
$ vips gamma t.v output.tif
</programlisting>

      is faster than using <code>.tif</code> for the temporary intermediate 
      image. This section documents the VIPS file format. 
    </para>
    
    <para>
      VIPS comes with a command-line program called 
      <command>vipsedit</command> which is useful for destructively changing 
      fields in a vips image. The <command>vipsheader</command> program can be 
      used to extract any metadata.
    </para>

    <para>
      VIPS files come in three parts. First, there is a 64-byte header, 
      containing an identifying magic number and a set of very basic fields, 
      such as image width in pixels. Next, the image data is stored as a set 
      of band-interleaved scanlines, from the top of the image to the bottom.
      Finally, after the pixel data comes an optional block of XML containing 
      any extra metadata, such as an ICC profile or the EXIF data. 
    </para>
  </refsect3>

  <refsect3 id="vips-format-header">
    <title>The header</title>
    <para>
      The fields in the VIPS header are always stored least-significant byte 
      first (Intel ordering). Only the most basic information about the image 
      is in the header: most metadata is stored in the XML extension block 
      after the pixel data.
    </para>

    <para>
      If the first four bytes of the file are in order 08 f2 a6 b6, the image 
      data (see the next section)
      is stored in Intel byte order (LSB first) and will need to be swapped 
      if read on a SPARC-style machine (MSB first). 
      If the magic number is b6 a6 f2 08, the image data is in SPARC order
      and will need to swapped if read on an Intel-style machine. libvips does 
      this swapping automatically. 

      <table>
        <title>The VIPS header</title>
        <tgroup cols='4' align='left' colsep='1' rowsep='1'>
          <thead>
            <row>
              <entry>Bytes</entry>
              <entry>Type</entry>
              <entry>VIPS name</entry>
              <entry>Meaning</entry>
            </row>
          </thead>
          <tbody>

            <row>
              <entry>0 -- 3</entry>
              <entry></entry>
              <entry></entry>
              <entry>VIPS magic number: 08 f2 a6 b6, or b6 a6 f2 08</entry>
            </row>

            <row>
              <entry>4 -- 7</entry>
              <entry>int32</entry>
              <entry><code>width</code></entry>
              <entry>Width of image, in pixels</entry>
            </row>

            <row>
              <entry>8 -- 11</entry>
              <entry>int32</entry>
              <entry><code>height</code></entry>
              <entry>Height of image, in pixels</entry>
            </row>

            <row>
              <entry>12 -- 15</entry>
              <entry>int32</entry>
              <entry><code>bands</code></entry>
              <entry>Number of image bands</entry>
            </row>

            <row>
              <entry>16 -- 19</entry>
              <entry></entry>
              <entry></entry>
              <entry>Unused</entry>
            </row>

            <row>
              <entry>20 -- 23</entry>
              <entry>#VipsBandFormat</entry>
              <entry><code>format</code></entry>
              <entry>Band format</entry>
            </row>

            <row>
              <entry>24 -- 27</entry>
              <entry>#VipsCoding</entry>
              <entry><code>coding</code></entry>
              <entry>Image coding</entry>
            </row>

            <row>
              <entry>28 -- 31</entry>
              <entry>#VipsInterpretation</entry>
              <entry><code>interpretation</code></entry>
              <entry>Pixel interpretation</entry>
            </row>

            <row>
              <entry>32 -- 35</entry>
              <entry>float32</entry>
              <entry><code>xres</code></entry>
              <entry>Horizontal resolution, in pixels per millimetre</entry>
            </row>

            <row>
              <entry>36 -- 39</entry>
              <entry>float32</entry>
              <entry><code>yres</code></entry>
              <entry>Vertical resolution, in pixels per millimetre</entry>
            </row>

            <row>
              <entry>40 -- 47</entry>
              <entry></entry>
              <entry></entry>
              <entry>Unused</entry>
            </row>

            <row>
              <entry>48 -- 51</entry>
              <entry>int32</entry>
              <entry><code>xoffset</code></entry>
              <entry>Horizontal offset of origin, in pixels</entry>
            </row>

            <row>
              <entry>52 -- 55</entry>
              <entry>int32</entry>
              <entry><code>yoffset</code></entry>
              <entry>Vertical offset of origin, in pixels</entry>
            </row>

            <row>
              <entry>56 -- 63</entry>
              <entry></entry>
              <entry></entry>
              <entry>Unused</entry>
            </row>

          </tbody>
        </tgroup>
      </table>
    </para>

  </refsect3>

  <refsect3 id="vips-format-data">
    <title>The image data</title>
    <para>
      If <code>coding</code> is set to #VIPS_CODING_NONE, pixels are stored in 
      native C format, that is, the native format of the 
      machine that wrote the data. If you open a big-endian image on a 
      little-endian machine, VIPS will automatically byte-swap for you.
      VIPS has 10 band formats, see #VipsBandFormat.
      Image data is stored as a simple list of scanlines, from the top of the 
      image to the bottom. Pixels are band-interleaved, so RGBRGBRGBRGB, 
      for example. There is no padding at the end of scanlines. 
    </para>
 
    <para>
      If <code>coding</code> is set to #VIPS_CODING_LABQ, each pixel is four 
      bytes, with 10 bits for L* and 11 bits for each of a* and b*. These
      32 bits are packed into 4 bytes, with the most significant 8 bits of each
      value in the first 3 bytes, and the left-over bits packed into the final
      byte as 2:3:3.
    </para>

    <para>
      If <code>coding</code> is set to #VIPS_CODING_RAD, each pixel is 
      RGB or XYZ float, with 8 bits of mantissa
      and then 8 bits of exponent, shared between the three channels. This 
      coding style is used by the Radiance family of programs (and the HDR 
      format) commonly used for HDR imaging.
    </para>

    <para>
      Other values of <code>coding</code> can set other coding styles. Use 
      VIPS_IMAGE_SIZEOF_IMAGE() to calculate the size of the image data 
      section. 
    </para>

  </refsect3>

  <refsect3 id="vips-format-metadata">
    <title>The metadata</title>
    <para>
      Following the image data is a chunk of XML holding a simple list of 
      name-value pairs. Binary data is encoded with base64. Use 
      vips_image_set() and friends to set and get image metadata. 
    </para>

    <para>
      You can use <command>vipsheader -f getext some_file.v</command> to get 
      the XML from a VIPS image, and 
      <command>vipsedit --setext some_file.v &lt; file.xml</command> to 
      replace the XML.  
    </para>

  </refsect3>

</refentry>
