= sng(1) =
:doctype: manpage
// SPDX-License-Identifier: BSD-2-Clause
// SPDX-FileCopyrightText: (C) Eric S. Raymond <esr@thyrsus.com>

== NAME ==
sng - compiler/decompiler for Scriptable Network Graphics

== SYNOPSIS ==
*csng* [file...]

[[description]]
== DESCRIPTION ==

The +sng+ program translates between PNG (Portable Network Graphics)
format and SNG (Scriptable Network Graphics) format.  SNG is a
printable and editable minilanguage for describing PNG files.  With
sng, it is easy to view and edit exotic PNG chunks not supported by
graphics editors; also, since SNG is easy to generate from scripts,
sng may be useful at the end of a pipeline that programmatically
generates PNG images.

An SNG description consists of a series of chunk specifications in a
simple editable text format.  These generally correspond one-for-one
to PNG chunks.  There is one exception; the IMAGE chunk
specification is automatically translated into an IDAT chunk (doing
appropriate interlacing, compression, etcetera).

Given no file arguments, +sng+ translates stdin
to stdout.  In this mode, it checks the first character. If that
character is printable, the input stream is assumed to contain SNG;
+sng+ looks for an #SNG leader and tries to translate
the file to PNG.  If the character is non-printable, the input stream
is assumed to contain PNG; +sng+ tries to translate
it to SNG.

For each file that +sng+ operates on, it does
its conversion according to the file extension (.png or .sng).  The
result file has the same name left of the dot as the original, but the
opposite extension and type.

The -V option makes +sng+ identify itself and its version, then exit.

//The -i option causes IDAT chunks in a PNG to
//be dumped in raw form as IDAT chunks rather than as a reassembled
//IMAGE.

The -v option makes +sng+ report on what files it is converting.

[[sng_language_syntax]]
== SNG LANGUAGE SYNTAX ==
In general, the SNG language is token-oriented with tokens separated
by whitespace.  Anywhere that whitespace may appear, a "#" comment
leader causes all characters up to the next following newline to be
ignored.  The characters ":" and ";" are treated as whitespace, except
the ";" terminates a data element (see below).

In the syntax descriptions below, lines between {} may occur in any
order. Elements bracketed in [] are optional; a sequence bracketed by
[]* may be repeated any number of times.  Elements separated by | are
alternatives.  Elements separated by plus signs are an attribute set;
any sequence of one or more of those element tokens is valid.

The elements <byte>, <short>, <long>,
<float>, <string> are byte numeric, short-integer numeric,
long-integer numeric, and float numeric literals respectively (all
unsigned).  The <slong> element is a signed long-numeric
literal. All numerics use C conventions; that is, they are decimal
unless led by 0x (hex) or 0 (octal).

The element <string> is any number of doublequote-delimited character
string literals.  C-style escapes (\n, \t, \b, \r or \ followed by
octal or hex digits) are interpreted.  The result is the concatenation
of all the literals.

The element <keyword> is a doublequote-delimited PNG
keyword; that is, a string of no more than 79 printable Latin-1
characters or spaces, with no leading and no trailing and no
consecutive spaces.

A <data> element consists of a sequence of byte specifications in any
of the following formats. Either '}' or ';' ends a data literal; '}'
also ends the enclosing chunk.

1. _string_ format is an SNG string literal or sequence of string
literals (see above). The bytes of data are the string contents.

2. _base64_ format is signaled by the leading token 'base64'.  This
encoding can only be used when the values of all bytes are less than 64.
It encodes each byte as a single character, with decimal digits
representing values 0-9, followed by A-Z for 10-35, followed by a-z
for 36-61, followed by + for 62 and / for 63.  Base64 format can be
used if the image either has total (color plus alpha) bit depth of
four or less, or it is a spaletted image with 64 or fewer colors.
Whitespace is ignored.  Note that this encoding is only very loosely
related to RFC2045 base-64 encoding, which uses a different mapping of
bytes to values, and supports encoding of arbitrary binary data.

3. _hex_ format is signaled by the leading token "hex". In hex format,
each byte is specified by two hex digits (0123456789abcdef), most
significant first.  Whitespace is ignored.

4. _P1_ format is Portable Bit Map (PBM) format P1.  A decimal height
and width follow; it is a fatal error for them to fail to match the
IHDR dimensions.  Following this, the only non-whitespace characters
are expected to be "0" and "1", with the obvious values.  Whitespace
is ignored.

5. _P3_ format is Portable Pixel Map (PPM) format P3.  A decimal
height and width follow; it is a fatal error for them to fail to match
the IHDR dimensions.  A maximum channel value in decimal follows; it
is a fatal error for any following channel value to exceed this value.
Following this are triples of decimal channel values representing RGB
triples.  Whitespace separates decimal channel values but is otherwise
ignored.

An <rgb> element may be expanded to:

---
(<byte>, <byte>, <byte>) | <string>
---

That is, it is either a paren-enclosed list of RGB values or a string
naming a color named in the X RGB database.  Note that color names are
not necessarily portable between hosts or even displays, due to
different screen gammas and colorimetric biases.  For this
reason, the SNG decompiler generates color names in comments.

IMAGE segments contain unpacked and uninterlaced raster data.  There
will be exactly one IMAGE per SNG dump, containing the pixel data from
all IDAT chunks, unless the -i option is on.  In that case, there will
be multiple IDAT chunks containing raw (compressed) image data.

The options member of an IMAGE chunk (if present) sets image write
transformations, supplying the third argument of the png_write_png()
call used for output.  Note that for images with a bit depth of less
than 8, there is a default "packing" transformation.  Consult the
libpng(3) manual page for details.

Every SNG file must begin with the string "#SNG", followed by optional
SNG version information, followed by a colon (":", ASCII 58)
character.  The remainder of the first line is ignored by SNG.

Comments in the syntax diagram describe intended semantics.  This
specification should be read in conjunction with the PNG standard.

---
IHDR {
   height <long>
   width <long>
   bitdepth <byte> 
   [using grayscale+color+palette+alpha]
   [with interlace]			# Adam7 assumed if interlacing on
}

PLTE {
   [<rgb>]*				# RGB triples or X color names
}

IDAT {
   <data>
}

gAMA {<float>}

cHRM {
   white (<float>,<float>)      # White point x and y
   red (<float>,<float>)
   green (<float>,<float>)
   blue (<float>,<float>)
}

sRGB {<byte>}                   # Colorimetry intent, range 0-3

iCCP {                          # International Color Consortium profile
   name <keyword>
   profile <data>
}

sBIT {
   red <byte>                   # Color images only
   blue <byte>                  # Color images only
   green <byte>                 # Color images only
   gray <byte>                  # Grayscale images only
   alpha <byte>                 # Images with alpha only
}

bKGD {
   red <short>                  # Color images only
   blue <short>                 # Color images only
   green <short>                # Color images only
   gray <short>                 # Grayscale images only
   index <byte>                 # Paletted images only
}

hIST {
   <short> [, <short>]*         # Count must match palette size
}

tRNS {
   [gray <short>]               # Grayscale images only
   [red <short>]                # True-color images only
   [green <short>]              # True-color images only
   [blue <short>]               # True-color images only
   [<byte>]*                    # Paletted images only
}

pHYs {
   xpixels <long>
   ypixels <long>
   [per meter]
}

tIME {
   year <short>
   month <byte>
   day <byte>
   hour <byte>
   minute <byte>
   second <byte>
}

tEXt {                          # Ordinary text chunk
  keyword <keyword>
  text <string>
}

zTXt {                          # Compressed text chunk
  keyword <keyword>
  text <string>
}

iTXt {                          # International UTF-8 keyword
  language <keyword>
  keyword <keyword>
  translated <keyword>          # Translation of the keyword
  text <string>
  [compressed]
}

oFFs {
  xoffset <slong>
  yoffset <slong> 
  [unit pixels|micrometers]*
}

sPLT {
   name <keyword>
   depth <byte>
   [<rgb>, <short>, <short>]*    # Color followed by alpha and frequency
}

pCAL {
   name <keyword>
   x0 <slong>
   x1 <slong>
   mapping linear|euler|exponential|hyperboli   unit <string>
   [parameters <string>] 
}

sCAL {
   unit meter|radian
   width <string>
   height <string>
}

IMAGE {
   options identity+packing+packswap+invert_mono
              +shift+bgr+swap_alpha+invert_alpha+swap_endian+strip_filler
   pixels <data>
}

gIFg {
   disposal <byte>
   input <byte>
   delay <short>
}

gIFx {
   identifier <string>                # Must be 8 characters
   code <string>                      # Must be 3 characters
   data <data>
}

private <string> {                    # Private chunk declaration
   <data>
}
---



[[bugs]]
== BUGS ==
The -i option doesn't work yet, and won't until libpng's ability to
suppress special handling of IDATs is working.  See the
distribution TODO file for other minor problems.


[[files]]
== FILES ==
rgb.txt::
    The X colorname database, used for RGB-to-name mappings in the
    decompiler and name-to-RGB mappings in the compiler. 

[[see_also]]
== SEE ALSO ==

pbm(5), ppm(5).

[[author]]
== AUTHOR ==
Eric S. Raymond <esr@snark.thyrsus.com> December 1999.
The SNG home page is at http://sng.sourceforge.net/

For more information about PNG, see the
PNG website at http://www.libpng.org/pub/png/

The W3C recommendation is
http://www.w3.org/TR/2003/PR-PNG-20030520/index-noobject.html[
Portable Network Graphics (PNG) Specification (Second Edition)].  The
PNG specification is also ISO/IEC 15948.

// end
