#! /usr/bin/env python2
# coding: utf-8
from __future__ import (unicode_literals, division, absolute_import,
                        print_function)

__license__   = 'GPL v3'
__copyright__ = '2011, Anthon van der Neut <A.van.der.Neut@ruamel.eu>'

# Copyright (C) 2011 Anthon van der Neut, Ruamel bvba
# Adapted from Leon Bottou's djvulibre C++ code,
# ( ZPCodec.{cpp,h} and BSByteStream.{cpp,h} )
# that code was first converted to C removing any dependencies on the DJVU libre
# framework for ByteStream, making it into a ctypes callable shared object
# then to python, and remade into a class
original_copyright_notice = '''
//C- -------------------------------------------------------------------
//C- DjVuLibre-3.5
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
//C- Copyright (c) 2001  AT&T
//C-
//C- This software is subject to, and may be distributed under, the
//C- GNU General Public License, either Version 2 of the license,
//C- or (at your option) any later version. The license should have
//C- accompanied the software or you may obtain a copy of the license
//C- from the Free Software Foundation at http://www.fsf.org .
//C-
//C- This program is distributed in the hope that it will be useful,
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//C- GNU General Public License for more details.
//C-
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
//C- Lizardtech Software.  Lizardtech Software has authorized us to
//C- replace the original DjVu(r) Reference Library notice by the following
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
//C-
//C-  ------------------------------------------------------------------
//C- | DjVu (r) Reference Library (v. 3.5)
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
//C- | 6,058,214 and patents pending.
//C- |
//C- | This software is subject to, and may be distributed under, the
//C- | GNU General Public License, either Version 2 of the license,
//C- | or (at your option) any later version. The license should have
//C- | accompanied the software or you may obtain a copy of the license
//C- | from the Free Software Foundation at http://www.fsf.org .
//C- |
//C- | The computer code originally released by LizardTech under this
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
//C- | non-exclusive license to make, use, sell, or otherwise dispose of
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
//C- | General Public License.   This grant only confers the right to
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
//C- | the extent such infringement is reasonably necessary to enable
//C- | recipient to make, have made, practice, sell, or otherwise dispose
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
//C- | any greater extent that may be necessary to utilize further
//C- | modifications or combinations.
//C- |
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//C- +------------------------------------------------------------------
//
// $Id: BSByteStream.cpp,v 1.9 2007/03/25 20:48:29 leonb Exp $
// $Name: release_3_5_23 $
'''


MAXBLOCK = 4096
FREQMAX = 4
CTXIDS = 3
MAXLEN = 1024 ** 2

# Exception classes used by this module.


class BZZDecoderError(Exception):

    """This exception is raised when BZZDecode runs into trouble
    """

    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return "BZZDecoderError: %s" % (self.msg)


# This table has been designed for the ZPCoder
#   * by running the following command in file 'zptable.sn':
#   * (fast-crude (steady-mat 0.0035  0.0002) 260)))
default_ztable = [  # {{{
  (0x8000, 0x0000, 84, 145),    # 000: p=0.500000 (    0,    0)
  (0x8000, 0x0000, 3, 4),       # 001: p=0
.500000 (    0,    0)
  (0x8000, 0x0000, 4, 3),       # 002: p=0.500000 (    0,    0)
  (0x6bbd, 0x10a5, 5, 1),       # 003: p=0.465226 (    0,    0)
  (0x6bbd, 0x10a5, 6, 2),       # 004: p=0.465226 (    0,    0)
  (0x5d45, 0x1f28, 7, 3),       # 005: p=0.430708 (    0,    0)
  (0x5d45, 0x1f28, 8, 4),       # 006: p=0.430708 (    0,    0)
  (0x51b9, 0x2bd3, 9, 5),       # 007: p=0.396718 (    0,    0)
  (0
x51b9, 0x2bd3, 10, 6),      # 008: p=0.396718 (    0,    0)
  (0x4813, 0x36e3, 11, 7),      # 009: p=0.363535 (    0,    0)
  (0x4813, 0x36e3, 12, 8),      # 010: p=0.363535 (    0,    0)
  (0x3fd5, 0x408c, 13, 9),      # 011: p=0.331418 (    0,    0)
  (0x3fd5, 0x408c, 14, 10),     # 012: p=0.331418 (    0,    0)
  (0x38b1, 0x48fd, 15, 11),     # 013: p=0.300585 (    0,    0)
  (0x38b1, 0x48fd, 16, 12),     # 014: p=0.300585 (    0,    0)
  (0x3275, 0x505d, 17, 13),     # 015: p=0.271213 (    0,    0)
  (0x3275, 0x505d, 18, 14),     # 016: p=0.271213 (    0,    0)
  (0x2cfd, 0x56d0, 19, 15),     # 017: p=0.243438 (    0,    0)
  (0x2cfd, 0x56d0, 20, 16),     # 018: p=0.243438 (    0,    0)
  (0x2825, 0x5c71, 21, 17),     # 019: p=0.217391 (    0,    0)
  (0x2825, 0x5c71, 22, 18),     # 020: p=0.217391 (    0,    0)
  (0x23ab, 0x615b, 23, 19),     # 021: p=0.193150 (    0,    0)
  (0x23ab, 0x615b, 24, 20),     # 022: p=0.193150 (    0,    0)
  (0x1f87, 0x65a5, 25, 21),     # 023: p=0.170728 (    0,    0)
  (0x1f87, 0x65a5, 26, 22),     # 024: p=0.170728 (    0,    0)
  (0x1bbb, 0x6962, 27, 23),     # 025: p=0.150158 (    0,    0)
  (0x1bbb, 0x6962, 28, 24),     # 026: p=0.150158 (    0,    0)
  (0x1845, 0x6ca2, 29, 25),     # 027: p=0.131418 (    0,    0)
  (0x1845, 0x6ca2, 30, 26),     # 028: p=0.131418 (    0,    0)
  (0x1523, 0x6f74, 31, 27),     # 029: p=0.114460 (    0,    0)
  (0x1523, 0x6f74, 32, 28),     # 030: p=0.114460 (    0,    0)
  (0x1253, 0x71e6, 33, 29),     # 031: p=0.099230 (    0,    0)
  (0x1253, 0x71e6, 34, 30),     # 032: p=0.099230 (    0,    0)
  (0x0fcf, 0x7404, 35, 31),     # 033: p=0.085611 (    0,    0)
  (0x0fcf, 0x7404, 36, 32),     # 034: p=0.085611 (    0,    0)
  (0x0d95, 0x75d6, 37, 33),     # 035: p=0.073550 (    0,    0)
  (0x0d95, 0x75d6, 38, 34),     # 036: p=0.073550 (    0,    0)
  (0x0b9d, 0x7768, 39, 35),     # 037: p=0.062888 (    0,    0)
  (0x0b9d, 0x7768, 40, 36),     # 038: p=0.062888 (    0,    0)
  (0x09e3, 0x78c2, 41, 37),     # 039: p=0.053539 (    0,    0)
  (0x09e3, 0x78c2, 42, 38),     # 040: p=0.053539 (    0,    0)
  (0x0861, 0x79ea, 43, 39),     # 041: p=0.045365 (    0,    0)
  (0x0861, 0x79ea, 44, 40),     # 042: p=0.045365 (    0,    0)
  (0x0711, 0x7ae7, 45, 41),     # 043: p=0.038272 (    0,    0)
  (0x0711, 0x7ae7, 46, 42),     # 044: p=0.038272 (    0,    0)
  (0x05f1, 0x7bbe, 47, 43),     # 045: p=0.032174 (    0,    0)
  (0x05f1, 0x7bbe, 48, 44),     # 046: p=0.032174 (    0,    0)
  (0x04f9, 0x7c75, 49, 45),     # 047: p=0.026928 (    0,    0)
  (0x04f9, 0x7c75, 50, 46),     # 048: p=0.026928 (    0,    0)
  (0x0425, 0x7d0f, 51, 47),     # 049: p=0.022444 (    0,    0)
  (0x0425, 0x7d0f, 52, 48),     # 050: p=0.022444 (    0,    0)
  (0x0371, 0x7d91, 53, 49),     # 051: p=0.018636 (    0,    0)
  (0x0371, 0x7d91, 54, 50),     # 052: p=0.018636 (    0,    0)
  (0x02d9, 0x7dfe, 55, 51),     # 053: p=0.015421 (    0,    0)
  (0x02d9, 0x7dfe, 56, 52),     # 054: p=0.015421 (    0,    0)
  (0x0259, 0x7e5a, 57, 53),     # 055: p=0.012713 (    0,    0)
  (0x0259, 0x7e5a, 58, 54),     # 056: p=0.012713 (    0,    0)
  (0x01ed, 0x7ea6, 59, 55),     # 057: p=0.010419 (    0,    0)
  (0x01ed, 0x7ea6, 60, 56),     # 058: p=0.010419 (    0,    0)
  (0x0193, 0x7ee6, 61, 57),     # 059: p=0.008525 (    0,    0)
  (0x0193, 0x7ee6, 62, 58),     # 060: p=0.008525 (    0, 