diff mupdf-source/thirdparty/zint/backend/tif_lzw.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mupdf-source/thirdparty/zint/backend/tif_lzw.h	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,382 @@
+/*  tif_lzw.h - LZW compression for TIFF */
+/*
+    libzint - the open source barcode library
+    Copyright (C) 2021-2024 Robin Stuart <rstuart114@gmail.com>
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the project nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+ */
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#ifndef Z_TIF_LZW_H
+#define Z_TIF_LZW_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Adapted from TIFF Library 4.2.0 libtiff/tif_lzw.c */
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+/*
+ * TIFF Library.
+ * Rev 5.0 Lempel-Ziv & Welch Compression Support
+ *
+ * This code is derived from the compress program whose code is
+ * derived from software contributed to Berkeley by James A. Woods,
+ * derived from original work by Spencer Thomas and Joseph Orost.
+ *
+ * The original Berkeley copyright notice appears below in its entirety.
+ */
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#define MAXCODE(n)  ((1L << (n)) - 1)
+
+/*
+ * The TIFF spec specifies that encoded bit
+ * strings range from 9 to 12 bits.
+ */
+#define BITS_MIN        9               /* start with 9 bits */
+#define BITS_MAX        12              /* max of 12 bit strings */
+/* predefined codes */
+#define CODE_CLEAR      256             /* code to clear string table */
+#define CODE_EOI        257             /* end-of-information code */
+#define CODE_FIRST      258             /* first free code entry */
+#define CODE_MAX        MAXCODE(BITS_MAX)
+#define HSIZE           9001L           /* 91% occupancy */
+#define HSHIFT          (13 - 8)
+
+/*
+ * Encoding-specific state.
+ */
+typedef uint16_t tif_lzw_hcode; /* codes fit in 16 bits */
+typedef struct {
+    long    hash;
+    tif_lzw_hcode code;
+} tif_lzw_hash;
+
+#define CHECK_GAP   10000       /* ratio check interval */
+
+/*
+ * State block.
+ */
+typedef struct {
+    tif_lzw_hash *enc_hashtab;  /* kept separate for small machines */
+} tif_lzw_state;
+
+/*
+ * LZW Encoding.
+ */
+
+/*
+ * Reset encoding hash table.
+ */
+static void tif_lzw_cl_hash(tif_lzw_state *sp) {
+    register tif_lzw_hash *hp = &sp->enc_hashtab[HSIZE - 1];
+    register long i = HSIZE - 8;
+
+    do {
+        i -= 8;
+        hp[-7].hash = -1;
+        hp[-6].hash = -1;
+        hp[-5].hash = -1;
+        hp[-4].hash = -1;
+        hp[-3].hash = -1;
+        hp[-2].hash = -1;
+        hp[-1].hash = -1;
+        hp[ 0].hash = -1;
+        hp -= 8;
+    } while (i >= 0);
+
+    for (i += 8; i > 0; i--, hp--) {
+        hp->hash = -1;
+    }
+}
+
+#define CALCRATIO(sp, rat) { \
+    if (incount > 0x007fffff) { /* NB: shift will overflow */ \
+        rat = outcount >> 8; \
+        rat = (rat == 0 ? 0x7fffffff : incount / rat); \
+    } else \
+        rat = (incount << 8) / outcount; \
+}
+
+/* Explicit 0xff masking to make icc -check=conversions happy */
+#define PutNextCode(op_fmp, c) { \
+    nextdata = (nextdata << nbits) | c; \
+    nextbits += nbits; \
+    fm_putc((nextdata >> (nextbits - 8)) & 0xff, op_fmp); \
+    nextbits -= 8; \
+    if (nextbits >= 8) { \
+        fm_putc((nextdata >> (nextbits - 8)) & 0xff, op_fmp); \
+        nextbits -= 8; \
+    } \
+    outcount += nbits; \
+}
+
+/*
+ * Encode a chunk of pixels.
+ *
+ * Uses an open addressing double hashing (no chaining) on the
+ * prefix code/next character combination.  We do a variant of
+ * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
+ * relatively-prime secondary probe.  Here, the modular division
+ * first probe is gives way to a faster exclusive-or manipulation.
+ * Also do block compression with an adaptive reset, whereby the
+ * code table is cleared when the compression ratio decreases,
+ * but after the table fills.  The variable-length output codes
+ * are re-sized at this point, and a CODE_CLEAR is generated
+ * for the decoder.
+ */
+static int tif_lzw_encode(tif_lzw_state *sp, struct filemem *op_fmp, const unsigned char *bp, int cc) {
+    register long fcode;
+    register tif_lzw_hash *hp;
+    register int h, c;
+    tif_lzw_hcode ent;
+    long disp;
+
+    int nbits;              /* # of bits/code */
+    int maxcode;            /* maximum code for nbits */
+    int free_ent;           /* next free entry in hash table */
+    unsigned long nextdata; /* next bits of i/o */
+    long nextbits;          /* # of valid bits in nextdata */
+    long checkpoint;        /* point at which to clear table */
+    long ratio;             /* current compression ratio */
+    long incount;           /* (input) data bytes encoded */
+    long outcount;          /* encoded (output) bytes */
+
+    /*
+     * Reset encoding state at the start of a strip.
+     */
+    if (sp->enc_hashtab == NULL) {
+        sp->enc_hashtab = (tif_lzw_hash *) malloc(HSIZE * sizeof(tif_lzw_hash));
+        if (sp->enc_hashtab == NULL) {
+            return 0;
+        }
+    }
+
+    tif_lzw_cl_hash(sp); /* clear hash table */
+
+    nbits = BITS_MIN;
+    maxcode = MAXCODE(BITS_MIN);
+    free_ent = CODE_FIRST;
+    nextdata = 0;
+    nextbits = 0;
+    checkpoint = CHECK_GAP;
+    ratio = 0;
+    incount = 0;
+    outcount = 0;
+
+    ent = (tif_lzw_hcode) -1;
+
+    if (cc > 0) {
+        PutNextCode(op_fmp, CODE_CLEAR);
+        ent = *bp++; cc--; incount++;
+    }
+    while (cc > 0) {
+        c = *bp++; cc--; incount++;
+        fcode = ((long)c << BITS_MAX) + ent;
+        h = (c << HSHIFT) ^ ent; /* xor hashing */
+#ifdef _WINDOWS
+        /*
+         * Check hash index for an overflow.
+         */
+        if (h >= HSIZE) {
+            h -= HSIZE;
+        }
+#endif
+        hp = &sp->enc_hashtab[h];
+        if (hp->hash == fcode) {
+            ent = hp->code;
+            continue;
+        }
+        if (hp->hash >= 0) {
+            /*
+             * Primary hash failed, check secondary hash.
+             */
+            disp = HSIZE - h;
+            if (h == 0) {
+                disp = 1;
+            }
+            do {
+                /*
+                 * Avoid pointer arithmetic because of
+                 * wraparound problems with segments.
+                 */
+                if ((h -= disp) < 0) {
+                    h += HSIZE;
+                }
+                hp = &sp->enc_hashtab[h];
+                if (hp->hash == fcode) {
+                    ent = hp->code;
+                    goto hit;
+                }
+            } while (hp->hash >= 0);
+        }
+        /*
+         * New entry, emit code and add to table.
+         */
+        PutNextCode(op_fmp, ent);
+        ent = (tif_lzw_hcode) c;
+        hp->code = (tif_lzw_hcode) (free_ent++);
+        hp->hash = fcode;
+        if (free_ent == CODE_MAX - 1) {
+            /* table is full, emit clear code and reset */
+            tif_lzw_cl_hash(sp);
+            ratio = 0;
+            incount = 0;
+            outcount = 0;
+            free_ent = CODE_FIRST;
+            PutNextCode(op_fmp, CODE_CLEAR);
+            nbits = BITS_MIN;
+            maxcode = MAXCODE(BITS_MIN);
+        } else {
+            /*
+             * If the next entry is going to be too big for
+             * the code size, then increase it, if possible.
+             */
+            if (free_ent > maxcode) {
+                nbits++;
+                assert(nbits <= BITS_MAX);
+                maxcode = (int) MAXCODE(nbits);
+            } else if (incount >= checkpoint) {
+                long rat;
+                /*
+                 * Check compression ratio and, if things seem
+                 * to be slipping, clear the hash table and
+                 * reset state.  The compression ratio is a
+                 * 24+8-bit fractional number.
+                 */
+                checkpoint = incount + CHECK_GAP;
+                CALCRATIO(sp, rat);
+                if (rat <= ratio) {
+                    tif_lzw_cl_hash(sp);
+                    ratio = 0;
+                    incount = 0;
+                    outcount = 0;
+                    free_ent = CODE_FIRST;
+                    PutNextCode(op_fmp, CODE_CLEAR);
+                    nbits = BITS_MIN;
+                    maxcode = MAXCODE(BITS_MIN);
+                } else {
+                    ratio = rat;
+                }
+            }
+        }
+    hit:
+        ;
+    }
+
+    /*
+     * Finish off an encoded strip by flushing the last
+     * string and tacking on an End Of Information code.
+     */
+    if (ent != (tif_lzw_hcode) -1) {
+
+        PutNextCode(op_fmp, ent);
+        free_ent++;
+
+        if (free_ent == CODE_MAX - 1) {
+            /* table is full, emit clear code and reset */
+            outcount = 0;
+            PutNextCode(op_fmp, CODE_CLEAR);
+            nbits = BITS_MIN;
+        } else {
+            /*
+            * If the next entry is going to be too big for
+            * the code size, then increase it, if possible.
+            */
+            if (free_ent > maxcode) {
+                nbits++;
+                assert(nbits <= BITS_MAX);
+            }
+        }
+    }
+    PutNextCode(op_fmp, CODE_EOI);
+    /* Explicit 0xff masking to make icc -check=conversions happy */
+    if (nextbits > 0) {
+        fm_putc((nextdata << (8 - nextbits)) & 0xff, op_fmp);
+    }
+
+    return 1;
+}
+
+static void tif_lzw_cleanup(tif_lzw_state *sp) {
+    if (sp->enc_hashtab) {
+        free(sp->enc_hashtab);
+    }
+}
+
+static void tif_lzw_init(tif_lzw_state *sp) {
+    sp->enc_hashtab = NULL;
+}
+
+#ifdef  __cplusplus
+}
+#endif /* __cplusplus */
+
+/* vim: set ts=4 sw=4 et : */
+#endif /* Z_TIF_LZW_H */