/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

 function: basic shared codebook operations
 last mod: $Id: codebook.h 19457 2015-03-03 00:15:29Z giles $

 ********************************************************************/

#ifndef _V_CODEBOOK_H_
#define _V_CODEBOOK_H_

#include "ogg.h"

/* This structure encapsulates huffman and VQ style encoding books; it
   doesn't do anything specific to either.

   valuelist/quantlist are nonNULL (and q_* significant) only if
   there's entry->value mapping to be done.

   If encode-side mapping must be done (and thus the entry needs to be
   hunted), the auxiliary encode pointer will point to a decision
   tree.  This is true of both VQ and huffman, but is mostly useful
   with VQ.

*/

typedef struct static_codebook{
	int32_t     dim;        /* codebook dimensions (elements per vector) */
	int32_t     entries;    /* codebook entries */
	uint8_t*    lengthlist; /* codeword lengths in bits */

	/* mapping ***************************************************************/
	int         maptype;     /* 0=none
	                            1=implicitly populated values from map column
	                            2=listed arbitrary values */

	/* The below does a linear, single monotonic sequence mapping. */
	int32_t     q_min;      /* packed 32 bit FLOAT; quant value 0 maps to minval */
	int32_t     q_delta;    /* packed 32 bit FLOAT; val 1 - val 0 == delta */
	int         q_quant;    /* bits: 0 < quant <= 16 */
	int         q_sequencep;/* bitflag */

	int32_t*    quantlist;  /* map == 1: (int)(entries^(1/dim)) element column map
	                           map == 2: list of dim*entries quantized entry vals
	                         */
} static_codebook;

typedef struct codebook{
	int32_t     dim;            /* codebook dimensions (elements per vector) */
	int32_t     entries;        /* codebook entries */
	int32_t     used_entries;   /* populated codebook entries */
	const static_codebook* c;

	bint*       valuelist;      /* list of dim*entries actual entry values */
	uint32_t*   codelist;       /* list of bitstream codewords for each entry */

	int*        dec_index;      /* only used if sparseness collapsed */
	char*       dec_codelengths;
	uint32_t*   dec_firsttable;
	int         dec_firsttablen;
	int         dec_maxlength;
} codebook;

extern void vorbis_staticbook_destroy(static_codebook* b);
extern int vorbis_book_init_decode(codebook* dest, const static_codebook* source);
extern void vorbis_book_clear(codebook* b);

extern int32_t _book_maptype1_quantvals(const static_codebook* b);

extern static_codebook* vorbis_staticbook_unpack(oggpack_buffer* b);

extern int32_t vorbis_book_decode(const codebook* book, oggpack_buffer* b);
extern int32_t vorbis_book_decodevs_add(const codebook* book, bint* a, oggpack_buffer* b,int n);
extern int32_t vorbis_book_decodev_set(const codebook* book, bint* a, oggpack_buffer* b,int n);
extern int32_t vorbis_book_decodev_add(const codebook* book, bint* a, oggpack_buffer* b,int n);
extern int32_t vorbis_book_decodevv_add(const codebook* book, bint** a,
									int32_t off,int ch, oggpack_buffer* b,int n);

#endif
