summaryrefslogtreecommitdiffstats
path: root/kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp')
-rw-r--r--kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp465
1 files changed, 465 insertions, 0 deletions
diff --git a/kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp b/kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp
new file mode 100644
index 00000000..77334a45
--- /dev/null
+++ b/kviewshell/plugins/djvu/libdjvu/BSByteStream.cpp
@@ -0,0 +1,465 @@
+//C- -*- C++ -*-
+//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, Version 2. 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
+//C- distributed by Lizardtech Software. On July 19th 2002, Lizardtech
+//C- Software authorized us to replace the original DjVu(r) Reference
+//C- Library notice by the following text (see doc/lizard2002.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, Version 2. 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.8 2003/11/07 22:08:20 leonb Exp $
+// $Name: release_3_5_15 $
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#if NEED_GNUG_PRAGMAS
+# pragma implementation
+#endif
+
+// - Author: Leon Bottou, 07/1998
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "BSByteStream.h"
+#undef BSORT_TIMER
+#ifdef BSORT_TIMER
+#include "GOS.h"
+#endif
+
+
+#ifdef HAVE_NAMESPACES
+namespace DJVU {
+# ifdef NOT_DEFINED // Just to fool emacs c++ mode
+}
+#endif
+#endif
+
+class BSByteStream::Decode : public BSByteStream
+{
+public:
+ /** Creates a Static object for allocating the memory area of
+ length #sz# starting at address #buffer#. */
+ Decode(GP<ByteStream> bs);
+ ~Decode();
+ void init(void);
+ // Virtual functions
+ virtual size_t read(void *buffer, size_t sz);
+ virtual void flush(void);
+protected:
+ unsigned int decode(void);
+private:
+ bool eof;
+};
+
+// ========================================
+// --- Assertion
+
+#define ASSERT(expr) do{if(!(expr))G_THROW("assertion ("#expr") failed");}while(0)
+
+// ========================================
+// --- Construction
+
+BSByteStream::BSByteStream(GP<ByteStream> xbs)
+: offset(0), bptr(0), blocksize(0), size(0), bs(xbs),
+ gbs(xbs), gdata(data,0)
+{
+ // Initialize context array
+ memset(ctx, 0, sizeof(ctx));
+}
+
+BSByteStream::~BSByteStream() {}
+
+BSByteStream::Decode::Decode(GP<ByteStream> xbs)
+: BSByteStream(xbs), eof(false) {}
+
+void
+BSByteStream::Decode::init(void)
+{
+ gzp=ZPCodec::create(gbs,false,true);
+}
+
+BSByteStream::Decode::~Decode() {}
+
+GP<ByteStream>
+BSByteStream::create(GP<ByteStream> xbs)
+{
+ BSByteStream::Decode *rbs=new BSByteStream::Decode(xbs);
+ GP<ByteStream> retval=rbs;
+ rbs->init();
+ return retval;
+}
+
+void
+BSByteStream::Decode::flush()
+{
+ size = bptr = 0;
+}
+
+// ========================================
+// -- Decoding
+
+
+static int
+decode_raw(ZPCodec &zp, int bits)
+{
+ int n = 1;
+ const int m = (1<<bits);
+ while (n < m)
+ {
+ const int b = zp.decoder();
+ n = (n<<1) | b;
+ }
+ return n - m;
+}
+
+static inline int
+decode_binary(ZPCodec &zp, BitContext *ctx, int bits)
+{
+ int n = 1;
+ int m = (1<<bits);
+ ctx = ctx - 1;
+ while (n < m)
+ {
+ int b = zp.decoder(ctx[n]);
+ n = (n<<1) | b;
+ }
+ return n - m;
+}
+
+
+static inline void
+assignmtf(unsigned char xmtf[256])
+{
+ static const unsigned char mtf[256]={
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+ 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
+ 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
+ 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+ 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+ 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+ 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
+ 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
+ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
+ 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
+ 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
+ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
+ 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
+ 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
+ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
+ 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
+ memcpy(xmtf,mtf,sizeof(mtf));
+}
+
+unsigned int
+BSByteStream::Decode::decode(void)
+{
+ /////////////////////////////////
+ //////////// Decode input stream
+
+ int i;
+ // Decode block size
+ ZPCodec &zp=*gzp;
+ size = decode_raw(zp, 24);
+ if (!size)
+ return 0;
+ if (size>MAXBLOCK*1024)
+ G_THROW( ERR_MSG("ByteStream.corrupt") );
+ // Allocate
+ if ((int)blocksize < size)
+ {
+ blocksize = size;
+ if (data)
+ {
+ gdata.resize(0);
+ }
+ }
+ if (! data)
+ gdata.resize(blocksize);
+ // Decode Estimation Speed
+ int fshift = 0;
+ if (zp.decoder())
+ {
+ fshift += 1;
+ if (zp.decoder())
+ fshift += 1;
+ }
+ // Prepare Quasi MTF
+ static const unsigned char xmtf[256]={
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+ 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
+ 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
+ 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+ 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+ 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+ 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
+ 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
+ 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
+ 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
+ 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
+ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
+ 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
+ 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
+ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
+ 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
+ unsigned char mtf[256];
+ memcpy(mtf,xmtf,sizeof(xmtf));
+ unsigned int freq[FREQMAX];
+ memset(freq,0,sizeof(freq));
+ int fadd = 4;
+ // Decode
+ int mtfno = 3;
+ int markerpos = -1;
+ for (i=0; i<size; i++)
+ {
+ int ctxid = CTXIDS-1;
+ if (ctxid>mtfno) ctxid=mtfno;
+ BitContext *cx = ctx;
+ if (zp.decoder(cx[ctxid]))
+ { mtfno=0; data[i]=mtf[mtfno]; goto rotate; }
+ cx+=CTXIDS;
+ if (zp.decoder(cx[ctxid]))
+ { mtfno=1; data[i]=mtf[mtfno]; goto rotate; }
+ cx+=CTXIDS;
+ if (zp.decoder(cx[0]))
+ { mtfno=2+decode_binary(zp,cx+1,1); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+1;
+ if (zp.decoder(cx[0]))
+ { mtfno=4+decode_binary(zp,cx+1,2); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+3;
+ if (zp.decoder(cx[0]))
+ { mtfno=8+decode_binary(zp,cx+1,3); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+7;
+ if (zp.decoder(cx[0]))
+ { mtfno=16+decode_binary(zp,cx+1,4); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+15;
+ if (zp.decoder(cx[0]))
+ { mtfno=32+decode_binary(zp,cx+1,5); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+31;
+ if (zp.decoder(cx[0]))
+ { mtfno=64+decode_binary(zp,cx+1,6); data[i]=mtf[mtfno]; goto rotate; }
+ cx+=1+63;
+ if (zp.decoder(cx[0]))
+ { mtfno=128+decode_binary(zp,cx+1,7); data[i]=mtf[mtfno]; goto rotate; }
+ mtfno=256;
+ data[i]=0;
+ markerpos=i;
+ continue;
+ // Rotate mtf according to empirical frequencies (new!)
+ rotate:
+ // Adjust frequencies for overflow
+ int k;
+ fadd = fadd + (fadd>>fshift);
+ if (fadd > 0x10000000)
+ {
+ fadd >>= 24;
+ freq[0] >>= 24;
+ freq[1] >>= 24;
+ freq[2] >>= 24;
+ freq[3] >>= 24;
+ for (k=4; k<FREQMAX; k++)
+ freq[k] = freq[k]>>24;
+ }
+ // Relocate new char according to new freq
+ unsigned int fc = fadd;
+ if (mtfno < FREQMAX)
+ fc += freq[mtfno];
+ for (k=mtfno; k>=FREQMAX; k--)
+ mtf[k] = mtf[k-1];
+ for (; k>0 && fc>=freq[k-1]; k--)
+ {
+ mtf[k] = mtf[k-1];
+ freq[k] = freq[k-1];
+ }
+ mtf[k] = data[i];
+ freq[k] = fc;
+ }
+
+
+ /////////////////////////////////
+ ////////// Reconstruct the string
+
+ if (markerpos<1 || markerpos>=size)
+ G_THROW( ERR_MSG("ByteStream.corrupt") );
+ // Allocate pointers
+ unsigned int *posn;
+ GPBuffer<unsigned int> gposn(posn,blocksize);
+ memset(posn, 0, sizeof(unsigned int)*size);
+ // Prepare count buffer
+ int count[256];
+ for (i=0; i<256; i++)
+ count[i] = 0;
+ // Fill count buffer
+ for (i=0; i<markerpos; i++)
+ {
+ unsigned char c = data[i];
+ posn[i] = (c<<24) | (count[c] & 0xffffff);
+ count[c] += 1;
+ }
+ for (i=markerpos+1; i<size; i++)
+ {
+ unsigned char c = data[i];
+ posn[i] = (c<<24) | (count[c] & 0xffffff);
+ count[c] += 1;
+ }
+ // Compute sorted char positions
+ int last = 1;
+ for (i=0; i<256; i++)
+ {
+ int tmp = count[i];
+ count[i] = last;
+ last += tmp;
+ }
+ // Undo the sort transform
+ i = 0;
+ last = size-1;
+ while (last>0)
+ {
+ unsigned int n = posn[i];
+ unsigned char c = (posn[i]>>24);
+ data[--last] = c;
+ i = count[c] + (n & 0xffffff);
+ }
+ // Free and check
+ if (i != markerpos)
+ G_THROW( ERR_MSG("ByteStream.corrupt") );
+ return size;
+}
+
+
+
+// ========================================
+// -- ByteStream interface
+
+
+
+long
+BSByteStream::tell() const
+{
+ return offset;
+}
+
+size_t
+BSByteStream::Decode::read(void *buffer, size_t sz)
+{
+ if (eof)
+ return 0;
+ // Loop
+ int copied = 0;
+ while (sz>0 && !eof)
+ {
+ // Decode if needed
+ if (!size)
+ {
+ bptr = 0;
+ if (! decode())
+ {
+ size = 1 ;
+ eof = true;
+ }
+ size -= 1;
+ }
+ // Compute remaining
+ int bytes = size;
+ if (bytes > (int)sz)
+ bytes = sz;
+ // Transfer
+ if (buffer && bytes)
+ {
+ memcpy(buffer, data+bptr, bytes);
+ buffer = (void*)((char*)buffer + bytes);
+ }
+ size -= bytes;
+ bptr += bytes;
+ sz -= bytes;
+ copied += bytes;
+ offset += bytes;
+ }
+ // Return copied bytes
+ return copied;
+}
+
+
+#ifdef HAVE_NAMESPACES
+}
+# ifndef NOT_USING_DJVU_NAMESPACE
+using namespace DJVU;
+# endif
+#endif