Menu

#76 Support JBIG gray level images via multiple planes

open
nobody
None
5
2026-01-06
2026-01-03
No

According to documentation JBIG supports also gray level images.

GM cuts only the last signifficant bitplane :(!

O:\temp\60>gm identify lena.jbg
lena.jbg JBG 512x512+0+0 PseudoClass 2c 1-bit 180.3Ki 0.000u 0m:0.000017s

Both attached images are identical according to my tool:

<<< GComp >>> Compare two graphical images (c)1997-2025 F&TSoft, version 2.82
Comparing   Image types I1:100 (pl:8)(ch:1); I2:100 (pl:8)(ch:1)                                                                                         Both images have same contents.

Just from JBIG documentation:
Image data encoded with the JBIG algorithm is separated into planes, layers, and stripes. Each plane contains one bit per pixel. The number of planes stored in a JBIG data stream is the number of bits per pixel.

It is possible to generate as many image sample needed, my tool can convert gray level JBIG without any problem: https://ftsoft.com.cz/pictures/pictures.html

2 Attachments

Discussion

  • Jaroslav Fojtik

    Jaroslav Fojtik - 2026-01-03

    My JBIG module source code for inspiration.

     
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-03

    It is my understanding that there was an attempt in the standards organizations to use JBIG for more than bi-level images, but the effort failed. Are you aware of any implementations besides your own?

    Is the compression level very good as compared with modern compression algorithms?

    JBIG1 has been replaced by JBIG2.

     
  • Jaroslav Fojtik

    Jaroslav Fojtik - 2026-01-03

    It is written in JBIG library documentation. I have followed documentation only.

    If you want to encode a grey-scale image, you can use the library
    function

    void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
    int encode_planes,
    const unsigned char src, unsigned char *dest,
    int use_graycode);

    It separates an image in which each pixel is represented by one or
    more bytes into separate bit planes. The dest array of pointers to
    these bit planes can then be handed over to jbg_enc_init(). The
    variables x and y specify the width and height of the image in pixels,
    and has_planes specifies how many bits per pixel are used. As each
    pixel is represented by an integral number of consecutive bytes, of
    which each contains up to eight bits, the total length of the input
    image array src[] will therefore be x * y * ((has_planes + 7) / 8)
    bytes. The pixels are stored as usually in English reading order, and
    for each pixel the integer value is stored with the most significant
    byte coming first (Bigendian). This is exactly the format used in raw
    PGM files. In encode_planes, the number of bit planes that shall be
    extracted can be specified. This allows for instance to extract only
    the most significant 8 bits of a 12-bit image, where each pixel is
    represented by two bytes, by specifying has_planes = 12 and
    encode_planes = 8. If use_graycode is zero, then the binary code of
    the pixel integer values will be used instead of the Gray code. Plane
    0 contains always the most significant bit.

    The value planes is a standard part of JBIG file structure. This value could contain anything else than 1. It is not my invention.

     

    Last edit: Jaroslav Fojtik 2026-01-03
  • Jaroslav Fojtik

    Jaroslav Fojtik - 2026-01-03

    Compression seems to be signifficantly better. JBIG2 seems to be implemented in TIFF only.

    gconvert.exe lena.pcx lena.jbg
    gm convert -compress JBIG2 lena.pcx lena.tiff
    

    04.01.2026 00:38 184620 lena.jbg
    03.01.2026 19:17 254218 lena.pcx
    04.01.2026 00:39 263955 lena.tiff

     

    Last edit: Jaroslav Fojtik 2026-01-04
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-04

    There is no support for JBIG2 in the Windows build, or in libtiff either. If JBIG2 is accepted, it is being mapped to uncompressed. Compare with an ordinary JPEG or JP2 file instead.

     
  • Jaroslav Fojtik

    Jaroslav Fojtik - 2026-01-04

    This is not fair, JPEG is lossy format. JP2 is also lossy. Compression ratio is not comparable.

    The only effective lossless format is PNG
    04.01.2026 02:02 161 704 lena.png
    and PNG performs better, but this is not a compression competition. Gray level JBIG could occur in wild. Standard demo program pbmtojbg is capable to create gray JBIG.

     

    Last edit: Jaroslav Fojtik 2026-01-04
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-04
     
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-04

    JP2 supports lossless. Unfortunately, it was not working in GM due to a tiny bug (fixed in Mercurial).

    gm convert lena.pcx -define jp2:rate=1.0 lena.jp2

    WEBP supports lossless.

    gm convert lena.pcx -define webp:lossless=TRUE lena.webp

    JXL is supposed to support lossless, but for some reason requesting it is throwing an error in my build.

    Here are some sizes I obtain in various lossless formats. My Lena image is 256x256 whereas yours is 512x512:

    File Size
    lenaI16-lzma.tiff 42608
    lenaI16.pnm 196623
    lenaI16.tga 196626
    lenaI16-zip.tiff 40494
    lenaI16.bmp 131142
    lenaI16-zstd.tiff 38740
    lenaI16.webp 28396
    lenaI16.png 30933
    lenaI16.jp2: 27946
    lenaI16.pnm.gz 57219

    From the above, I see that lossless JP2 is the smallest. Can you beat it?

     
  • Jaroslav Fojtik

    Jaroslav Fojtik - 2026-01-04

    I has been explicitly written that I am not doing compression competition - it is only interesting. I originally want to support missing JBG variant, as it has been originally documented and implemented. JBG apparently does not achieve the best compression.

    Anyway, you have made test on a different image that I do not have. I have attached my image to this thread.

    JBG documentation claims to achieve better compression ratio on Grey code (not gray). But there is no information in a file whether Grey code or standard encoding used.

     

    Last edit: Jaroslav Fojtik 2026-01-04
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-04

    If I convert your lena.pcx to lossless JP2 it requires 159,285 bytes. Your JBIG file required 184,620 bytes.

     

    Last edit: Bob Friesenhahn 2026-01-04
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-06

    Ticket moved from /p/graphicsmagick/bugs/762/

    Can't be converted:

    • _milestone: v1.0_(example)
     
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-06
    • summary: Wrong support of JBIG gray level images --> Support of JBIG gray level images
     
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-06

    Changed this to a feature request given that multi-level JBIG does not appear to be in actual use (although documented) and it is less efficient than more modern algorithms for lossless compression.

     
  • Bob Friesenhahn

    Bob Friesenhahn - 2026-01-06
    • summary: Support of JBIG gray level images --> Support JBIG gray level images via multiple planes
     

Log in to post a comment.

MongoDB Logo MongoDB