Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

It's computer hardware, of course it's worth having <g> -- Espy on #Debian

computers / comp.compression / Picture compression in TeXnicard

o Picture compression in TeXnicardnews

Subject: Picture compression in TeXnicard
Newsgroups: comp.compression
Organization: NNTP Server
Date: Sat, 25 Apr 2020 19:10 UTC
Newsgroups: comp.compression
Subject: Picture compression in TeXnicard
Date: Sat, 25 Apr 2020 12:10:59 -0700
Organization: NNTP Server
Lines: 70
Message-ID: <>
Mime-Version: 1.0
User-Agent: bystand/1.1.1
X-Notice: Filtered by postfilter v. 0.9.2
View all headers
Here I will describe the experimental picture compression used in TeXnicard
(although it is in the Fossil repository with TeXnicard, it is not
currently used in TeXnicard, but in future it will be, for pictures that
are in the card database). It is a lossless compression, with three or four
channels, and either seven or eight bits per channel.

The picture converted from RGB to YCoCg, and then each channel is stored
separately, starting with Y, and then Cg, and then Co. (If there are four
channels, which would be the case if the picture is CMYK, then the fourth
channel is not converted, but is still predicted and huffed.)

First, predictions are made. The C code for making predictions is:

static int make_prediction(const unsigned char*p,int x,int y,int w) {
  int a=x?p[-1]:y?p[-w]:0;
  int b=y?p[-w]:x?p[-1]:0;
  int c=x&&y?p[-w-1]:a;
  if(c>=a && c>=b) return a<b?a:b;
  if(c<=a && c<=b) return a>b?a:b;
  return a+b-c;

For the Cg and Co channels, the valid range of values depends on the
values in the previous channels (this is why Cg comes before Co), so the
prediction is clipped into the valid range.

Predictions are then encoded as follows (where p is the predicted value,
and v is the actual value):

  if(p==v) return 0;
  if(p&128) v^=255,p^=255;
  if(v<p) return 2*(p-v)-1;
  if(v<p+p) return 2*(v-p);
  return v;

(For 7-bit predictions, the second line is changed.)

After that, rectangles where the predicted value is zero are found, and
are recorded, and then the remaining data is huffed. Each channel is
huffed separately.

In my experience, it tends to be somewhat better compression than PNG. The
intention of this format is to be stored as database blobs for the artwork
of cards, since using an external program to decode pictures in blobs
would be more difficult to do. External pictures can be stored in any
format; external programs are required to encode/decode. However, this
format I describe here could also be implemented for external pictures.

I invented this format in order to have a simple format included in the
program, which is public domain, without having to add too many additional
dependencies (the only dependencies are SQLite, Ghostscript, and whatever
are the dependencies of Ghostscript; because Ghostscript is AGPL, this
means those who distribute TeXnicard or make it available over a network
access are required to follow the requirements of AGPL). I did not want to
have a format which is too complicated, yet storing uncompressed pictures
would result in too big file size of the card database.

However, for pictures which are included in templates, one thing that
might be useful is some efficient way of storing versions of pictures for
multiple resolutions, in case you are rendering the cards at different
resolutions it can store an optimized picture for that resolution rather
than having to rescale it automatically. In addition to that, when CMYK
mode is used, TeXnicard supports up to four custom separations in addition
to the standard CMYK process colours.

Please mention whatever comments you have about this, please.

This signature intentionally left blank.
(But if it has these words, then actually it isn't blank, isn't it?)

rocksolid light 0.7.2