Path: blob/master/3rdparty/openexr/IlmImf/ImfHuf.cpp
16337 views
///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////3334353637//-----------------------------------------------------------------------------38//39// 16-bit Huffman compression and decompression.40//41// The source code in this file is derived from the 8-bit42// Huffman compression and decompression routines written43// by Christian Rouet for his PIZ image file format.44//45//-----------------------------------------------------------------------------4647#include <ImfHuf.h>48#include <ImfInt64.h>49#include <ImfAutoArray.h>50#include "Iex.h"51#include <string.h>52#include <assert.h>53#include <algorithm>545556using namespace std;57using namespace Iex;5859namespace Imf {60namespace {616263const int HUF_ENCBITS = 16; // literal (value) bit length64const int HUF_DECBITS = 14; // decoding bit size (>= 8)6566const int HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1; // encoding table size67const int HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size68const int HUF_DECMASK = HUF_DECSIZE - 1;697071struct HufDec72{ // short code long code73//-------------------------------74int len:8; // code length 075int lit:24; // lit p size76int * p; // 0 lits77};787980void81invalidNBits ()82{83throw InputExc ("Error in header for Huffman-encoded data "84"(invalid number of bits).");85}868788void89tooMuchData ()90{91throw InputExc ("Error in Huffman-encoded data "92"(decoded data are longer than expected).");93}949596void97notEnoughData ()98{99throw InputExc ("Error in Huffman-encoded data "100"(decoded data are shorter than expected).");101}102103104void105invalidCode ()106{107throw InputExc ("Error in Huffman-encoded data "108"(invalid code).");109}110111112void113invalidTableSize ()114{115throw InputExc ("Error in Huffman-encoded data "116"(invalid code table size).");117}118119120void121unexpectedEndOfTable ()122{123throw InputExc ("Error in Huffman-encoded data "124"(unexpected end of code table data).");125}126127128void129tableTooLong ()130{131throw InputExc ("Error in Huffman-encoded data "132"(code table is longer than expected).");133}134135136void137invalidTableEntry ()138{139throw InputExc ("Error in Huffman-encoded data "140"(invalid code table entry).");141}142143144inline Int64145hufLength (Int64 code)146{147return code & 63;148}149150151inline Int64152hufCode (Int64 code)153{154return code >> 6;155}156157158inline void159outputBits (int nBits, Int64 bits, Int64 &c, int &lc, char *&out)160{161c <<= nBits;162lc += nBits;163164c |= bits;165166while (lc >= 8)167*out++ = (c >> (lc -= 8));168}169170171inline Int64172getBits (int nBits, Int64 &c, int &lc, const char *&in)173{174while (lc < nBits)175{176c = (c << 8) | *(unsigned char *)(in++);177lc += 8;178}179180lc -= nBits;181return (c >> lc) & ((1 << nBits) - 1);182}183184185//186// ENCODING TABLE BUILDING & (UN)PACKING187//188189//190// Build a "canonical" Huffman code table:191// - for each (uncompressed) symbol, hcode contains the length192// of the corresponding code (in the compressed data)193// - canonical codes are computed and stored in hcode194// - the rules for constructing canonical codes are as follows:195// * shorter codes (if filled with zeroes to the right)196// have a numerically higher value than longer codes197// * for codes with the same length, numerical values198// increase with numerical symbol values199// - because the canonical code table can be constructed from200// symbol lengths alone, the code table can be transmitted201// without sending the actual code values202// - see http://www.compressconsult.com/huffman/203//204205void206hufCanonicalCodeTable (Int64 hcode[HUF_ENCSIZE])207{208Int64 n[59];209210//211// For each i from 0 through 58, count the212// number of different codes of length i, and213// store the count in n[i].214//215216for (int i = 0; i <= 58; ++i)217n[i] = 0;218219for (int i = 0; i < HUF_ENCSIZE; ++i)220n[hcode[i]] += 1;221222//223// For each i from 58 through 1, compute the224// numerically lowest code with length i, and225// store that code in n[i].226//227228Int64 c = 0;229230for (int i = 58; i > 0; --i)231{232Int64 nc = ((c + n[i]) >> 1);233n[i] = c;234c = nc;235}236237//238// hcode[i] contains the length, l, of the239// code for symbol i. Assign the next available240// code of length l to the symbol and store both241// l and the code in hcode[i].242//243244for (int i = 0; i < HUF_ENCSIZE; ++i)245{246int l = hcode[i];247248if (l > 0)249hcode[i] = l | (n[l]++ << 6);250}251}252253254//255// Compute Huffman codes (based on frq input) and store them in frq:256// - code structure is : [63:lsb - 6:msb] | [5-0: bit length];257// - max code length is 58 bits;258// - codes outside the range [im-iM] have a null length (unused values);259// - original frequencies are destroyed;260// - encoding tables are used by hufEncode() and hufBuildDecTable();261//262263264struct FHeapCompare265{266bool operator () (Int64 *a, Int64 *b) {return *a > *b;}267};268269270void271hufBuildEncTable272(Int64* frq, // io: input frequencies [HUF_ENCSIZE], output table273int* im, // o: min frq index274int* iM) // o: max frq index275{276//277// This function assumes that when it is called, array frq278// indicates the frequency of all possible symbols in the data279// that are to be Huffman-encoded. (frq[i] contains the number280// of occurrences of symbol i in the data.)281//282// The loop below does three things:283//284// 1) Finds the minimum and maximum indices that point285// to non-zero entries in frq:286//287// frq[im] != 0, and frq[i] == 0 for all i < im288// frq[iM] != 0, and frq[i] == 0 for all i > iM289//290// 2) Fills array fHeap with pointers to all non-zero291// entries in frq.292//293// 3) Initializes array hlink such that hlink[i] == i294// for all array entries.295//296297AutoArray <int, HUF_ENCSIZE> hlink;298AutoArray <Int64 *, HUF_ENCSIZE> fHeap;299300*im = 0;301302while (!frq[*im])303(*im)++;304305int nf = 0;306307for (int i = *im; i < HUF_ENCSIZE; i++)308{309hlink[i] = i;310311if (frq[i])312{313fHeap[nf] = &frq[i];314nf++;315*iM = i;316}317}318319//320// Add a pseudo-symbol, with a frequency count of 1, to frq;321// adjust the fHeap and hlink array accordingly. Function322// hufEncode() uses the pseudo-symbol for run-length encoding.323//324325(*iM)++;326frq[*iM] = 1;327fHeap[nf] = &frq[*iM];328nf++;329330//331// Build an array, scode, such that scode[i] contains the number332// of bits assigned to symbol i. Conceptually this is done by333// constructing a tree whose leaves are the symbols with non-zero334// frequency:335//336// Make a heap that contains all symbols with a non-zero frequency,337// with the least frequent symbol on top.338//339// Repeat until only one symbol is left on the heap:340//341// Take the two least frequent symbols off the top of the heap.342// Create a new node that has first two nodes as children, and343// whose frequency is the sum of the frequencies of the first344// two nodes. Put the new node back into the heap.345//346// The last node left on the heap is the root of the tree. For each347// leaf node, the distance between the root and the leaf is the length348// of the code for the corresponding symbol.349//350// The loop below doesn't actually build the tree; instead we compute351// the distances of the leaves from the root on the fly. When a new352// node is added to the heap, then that node's descendants are linked353// into a single linear list that starts at the new node, and the code354// lengths of the descendants (that is, their distance from the root355// of the tree) are incremented by one.356//357358make_heap (&fHeap[0], &fHeap[nf], FHeapCompare());359360AutoArray <Int64, HUF_ENCSIZE> scode;361memset (scode, 0, sizeof (Int64) * HUF_ENCSIZE);362363while (nf > 1)364{365//366// Find the indices, mm and m, of the two smallest non-zero frq367// values in fHeap, add the smallest frq to the second-smallest368// frq, and remove the smallest frq value from fHeap.369//370371int mm = fHeap[0] - frq;372pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());373--nf;374375int m = fHeap[0] - frq;376pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());377378frq[m ] += frq[mm];379push_heap (&fHeap[0], &fHeap[nf], FHeapCompare());380381//382// The entries in scode are linked into lists with the383// entries in hlink serving as "next" pointers and with384// the end of a list marked by hlink[j] == j.385//386// Traverse the lists that start at scode[m] and scode[mm].387// For each element visited, increment the length of the388// corresponding code by one bit. (If we visit scode[j]389// during the traversal, then the code for symbol j becomes390// one bit longer.)391//392// Merge the lists that start at scode[m] and scode[mm]393// into a single list that starts at scode[m].394//395396//397// Add a bit to all codes in the first list.398//399400for (int j = m; true; j = hlink[j])401{402scode[j]++;403404assert (scode[j] <= 58);405406if (hlink[j] == j)407{408//409// Merge the two lists.410//411412hlink[j] = mm;413break;414}415}416417//418// Add a bit to all codes in the second list419//420421for (int j = mm; true; j = hlink[j])422{423scode[j]++;424425assert (scode[j] <= 58);426427if (hlink[j] == j)428break;429}430}431432//433// Build a canonical Huffman code table, replacing the code434// lengths in scode with (code, code length) pairs. Copy the435// code table from scode into frq.436//437438hufCanonicalCodeTable (scode);439memcpy (frq, scode, sizeof (Int64) * HUF_ENCSIZE);440}441442443//444// Pack an encoding table:445// - only code lengths, not actual codes, are stored446// - runs of zeroes are compressed as follows:447//448// unpacked packed449// --------------------------------450// 1 zero 0 (6 bits)451// 2 zeroes 59452// 3 zeroes 60453// 4 zeroes 61454// 5 zeroes 62455// n zeroes (6 or more) 63 n-6 (6 + 8 bits)456//457458const int SHORT_ZEROCODE_RUN = 59;459const int LONG_ZEROCODE_RUN = 63;460const int SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;461const int LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN;462463464void465hufPackEncTable466(const Int64* hcode, // i : encoding table [HUF_ENCSIZE]467int im, // i : min hcode index468int iM, // i : max hcode index469char** pcode) // o: ptr to packed table (updated)470{471char *p = *pcode;472Int64 c = 0;473int lc = 0;474475for (; im <= iM; im++)476{477int l = hufLength (hcode[im]);478479if (l == 0)480{481int zerun = 1;482483while ((im < iM) && (zerun < LONGEST_LONG_RUN))484{485if (hufLength (hcode[im+1]) > 0 )486break;487im++;488zerun++;489}490491if (zerun >= 2)492{493if (zerun >= SHORTEST_LONG_RUN)494{495outputBits (6, LONG_ZEROCODE_RUN, c, lc, p);496outputBits (8, zerun - SHORTEST_LONG_RUN, c, lc, p);497}498else499{500outputBits (6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p);501}502continue;503}504}505506outputBits (6, l, c, lc, p);507}508509if (lc > 0)510*p++ = (unsigned char) (c << (8 - lc));511512*pcode = p;513}514515516//517// Unpack an encoding table packed by hufPackEncTable():518//519520void521hufUnpackEncTable522(const char** pcode, // io: ptr to packed table (updated)523int ni, // i : input size (in bytes)524int im, // i : min hcode index525int iM, // i : max hcode index526Int64* hcode) // o: encoding table [HUF_ENCSIZE]527{528memset (hcode, 0, sizeof (Int64) * HUF_ENCSIZE);529530const char *p = *pcode;531Int64 c = 0;532int lc = 0;533534for (; im <= iM; im++)535{536if (p - *pcode > ni)537unexpectedEndOfTable();538539Int64 l = hcode[im] = getBits (6, c, lc, p); // code length540541if (l == (Int64) LONG_ZEROCODE_RUN)542{543if (p - *pcode > ni)544unexpectedEndOfTable();545546int zerun = getBits (8, c, lc, p) + SHORTEST_LONG_RUN;547548if (im + zerun > iM + 1)549tableTooLong();550551while (zerun--)552hcode[im++] = 0;553554im--;555}556else if (l >= (Int64) SHORT_ZEROCODE_RUN)557{558int zerun = l - SHORT_ZEROCODE_RUN + 2;559560if (im + zerun > iM + 1)561tableTooLong();562563while (zerun--)564hcode[im++] = 0;565566im--;567}568}569570*pcode = (char *) p;571572hufCanonicalCodeTable (hcode);573}574575576//577// DECODING TABLE BUILDING578//579580//581// Clear a newly allocated decoding table so that it contains only zeroes.582//583584void585hufClearDecTable586(HufDec * hdecod) // io: (allocated by caller)587// decoding table [HUF_DECSIZE]588{589memset (hdecod, 0, sizeof (HufDec) * HUF_DECSIZE);590}591592593//594// Build a decoding hash table based on the encoding table hcode:595// - short codes (<= HUF_DECBITS) are resolved with a single table access;596// - long code entry allocations are not optimized, because long codes are597// unfrequent;598// - decoding tables are used by hufDecode();599//600601void602hufBuildDecTable603(const Int64* hcode, // i : encoding table604int im, // i : min index in hcode605int iM, // i : max index in hcode606HufDec * hdecod) // o: (allocated by caller)607// decoding table [HUF_DECSIZE]608{609//610// Init hashtable & loop on all codes.611// Assumes that hufClearDecTable(hdecod) has already been called.612//613614for (; im <= iM; im++)615{616Int64 c = hufCode (hcode[im]);617int l = hufLength (hcode[im]);618619if (c >> l)620{621//622// Error: c is supposed to be an l-bit code,623// but c contains a value that is greater624// than the largest l-bit number.625//626627invalidTableEntry();628}629630if (l > HUF_DECBITS)631{632//633// Long code: add a secondary entry634//635636HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));637638if (pl->len)639{640//641// Error: a short code has already642// been stored in table entry *pl.643//644645invalidTableEntry();646}647648pl->lit++;649650if (pl->p)651{652int *p = pl->p;653pl->p = new int [pl->lit];654655for (int i = 0; i < pl->lit - 1; ++i)656pl->p[i] = p[i];657658delete [] p;659}660else661{662pl->p = new int [1];663}664665pl->p[pl->lit - 1]= im;666}667else if (l)668{669//670// Short code: init all primary entries671//672673HufDec *pl = hdecod + (c << (HUF_DECBITS - l));674675for (Int64 i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++)676{677if (pl->len || pl->p)678{679//680// Error: a short code or a long code has681// already been stored in table entry *pl.682//683684invalidTableEntry();685}686687pl->len = l;688pl->lit = im;689}690}691}692}693694695//696// Free the long code entries of a decoding table built by hufBuildDecTable()697//698699void700hufFreeDecTable (HufDec *hdecod) // io: Decoding table701{702for (int i = 0; i < HUF_DECSIZE; i++)703{704if (hdecod[i].p)705{706delete [] hdecod[i].p;707hdecod[i].p = 0;708}709}710}711712713//714// ENCODING715//716717inline void718outputCode (Int64 code, Int64 &c, int &lc, char *&out)719{720outputBits (hufLength (code), hufCode (code), c, lc, out);721}722723724inline void725sendCode (Int64 sCode, int runCount, Int64 runCode,726Int64 &c, int &lc, char *&out)727{728static const int RLMIN = 32; // min count to activate run-length coding729730if (runCount > RLMIN)731{732outputCode (sCode, c, lc, out);733outputCode (runCode, c, lc, out);734outputBits (8, runCount, c, lc, out);735}736else737{738while (runCount-- >= 0)739outputCode (sCode, c, lc, out);740}741}742743744//745// Encode (compress) ni values based on the Huffman encoding table hcode:746//747748int749hufEncode // return: output size (in bits)750(const Int64* hcode, // i : encoding table751const unsigned short* in, // i : uncompressed input buffer752const int ni, // i : input buffer size (in bytes)753int rlc, // i : rl code754char* out) // o: compressed output buffer755{756char *outStart = out;757Int64 c = 0; // bits not yet written to out758int lc = 0; // number of valid bits in c (LSB)759int s = in[0];760int cs = 0;761762//763// Loop on input values764//765766for (int i = 1; i < ni; i++)767{768//769// Count same values or send code770//771772if (s == in[i] && cs < 255)773{774cs++;775}776else777{778sendCode (hcode[s], cs, hcode[rlc], c, lc, out);779cs=0;780}781782s = in[i];783}784785//786// Send remaining code787//788789sendCode (hcode[s], cs, hcode[rlc], c, lc, out);790791if (lc)792*out = (c << (8 - lc)) & 0xff;793794return (out - outStart) * 8 + lc;795}796797798//799// DECODING800//801802//803// In order to force the compiler to inline them,804// getChar() and getCode() are implemented as macros805// instead of "inline" functions.806//807808#define getChar(c, lc, in) \809{ \810c = (c << 8) | *(unsigned char *)(in++); \811lc += 8; \812}813814815#define getCode(po, rlc, c, lc, in, out, oe) \816{ \817if (po == rlc) \818{ \819if (lc < 8) \820getChar(c, lc, in); \821\822lc -= 8; \823\824unsigned char cs = (c >> lc); \825\826if (out + cs > oe) \827tooMuchData(); \828\829unsigned short s = out[-1]; \830\831while (cs-- > 0) \832*out++ = s; \833} \834else if (out < oe) \835{ \836*out++ = po; \837} \838else \839{ \840tooMuchData(); \841} \842}843844845//846// Decode (uncompress) ni bits based on encoding & decoding tables:847//848849void850hufDecode851(const Int64 * hcode, // i : encoding table852const HufDec * hdecod, // i : decoding table853const char* in, // i : compressed input buffer854int ni, // i : input size (in bits)855int rlc, // i : run-length code856int no, // i : expected output size (in bytes)857unsigned short* out) // o: uncompressed output buffer858{859Int64 c = 0;860int lc = 0;861unsigned short * outb = out;862unsigned short * oe = out + no;863const char * ie = in + (ni + 7) / 8; // input byte size864865//866// Loop on input bytes867//868869while (in < ie)870{871getChar (c, lc, in);872873//874// Access decoding table875//876877while (lc >= HUF_DECBITS)878{879const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK];880881if (pl.len)882{883//884// Get short code885//886887lc -= pl.len;888getCode (pl.lit, rlc, c, lc, in, out, oe);889}890else891{892if (!pl.p)893invalidCode(); // wrong code894895//896// Search long code897//898899int j;900901for (j = 0; j < pl.lit; j++)902{903int l = hufLength (hcode[pl.p[j]]);904905while (lc < l && in < ie) // get more bits906getChar (c, lc, in);907908if (lc >= l)909{910if (hufCode (hcode[pl.p[j]]) ==911((c >> (lc - l)) & ((Int64(1) << l) - 1)))912{913//914// Found : get long code915//916917lc -= l;918getCode (pl.p[j], rlc, c, lc, in, out, oe);919break;920}921}922}923924if (j == pl.lit)925invalidCode(); // Not found926}927}928}929930//931// Get remaining (short) codes932//933934int i = (8 - ni) & 7;935c >>= i;936lc -= i;937938while (lc > 0)939{940const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];941942if (pl.len)943{944lc -= pl.len;945getCode (pl.lit, rlc, c, lc, in, out, oe);946}947else948{949invalidCode(); // wrong (long) code950}951}952953if (out - outb != no)954notEnoughData ();955}956957958void959countFrequencies (Int64 freq[HUF_ENCSIZE],960const unsigned short data[/*n*/],961int n)962{963for (int i = 0; i < HUF_ENCSIZE; ++i)964freq[i] = 0;965966for (int i = 0; i < n; ++i)967++freq[data[i]];968}969970971void972writeUInt (char buf[4], unsigned int i)973{974unsigned char *b = (unsigned char *) buf;975976b[0] = i;977b[1] = i >> 8;978b[2] = i >> 16;979b[3] = i >> 24;980}981982983unsigned int984readUInt (const char buf[4])985{986const unsigned char *b = (const unsigned char *) buf;987988return ( b[0] & 0x000000ff) |989((b[1] << 8) & 0x0000ff00) |990((b[2] << 16) & 0x00ff0000) |991((b[3] << 24) & 0xff000000);992}993994} // namespace995996997//998// EXTERNAL INTERFACE999//100010011002int1003hufCompress (const unsigned short raw[],1004int nRaw,1005char compressed[])1006{1007if (nRaw == 0)1008return 0;10091010AutoArray <Int64, HUF_ENCSIZE> freq;10111012countFrequencies (freq, raw, nRaw);10131014int im, iM;1015hufBuildEncTable (freq, &im, &iM);10161017char *tableStart = compressed + 20;1018char *tableEnd = tableStart;1019hufPackEncTable (freq, im, iM, &tableEnd);1020int tableLength = tableEnd - tableStart;10211022char *dataStart = tableEnd;1023int nBits = hufEncode (freq, raw, nRaw, iM, dataStart);1024int dataLength = (nBits + 7) / 8;10251026writeUInt (compressed, im);1027writeUInt (compressed + 4, iM);1028writeUInt (compressed + 8, tableLength);1029writeUInt (compressed + 12, nBits);1030writeUInt (compressed + 16, 0); // room for future extensions10311032return dataStart + dataLength - compressed;1033}103410351036void1037hufUncompress (const char compressed[],1038int nCompressed,1039unsigned short raw[],1040int nRaw)1041{1042if (nCompressed == 0)1043{1044if (nRaw != 0)1045notEnoughData();10461047return;1048}10491050int im = readUInt (compressed);1051int iM = readUInt (compressed + 4);1052// int tableLength = readUInt (compressed + 8);1053int nBits = readUInt (compressed + 12);10541055if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE)1056invalidTableSize();10571058const char *ptr = compressed + 20;10591060AutoArray <Int64, HUF_ENCSIZE> freq;1061AutoArray <HufDec, HUF_DECSIZE> hdec;10621063hufClearDecTable (hdec);10641065hufUnpackEncTable (&ptr, nCompressed - (ptr - compressed), im, iM, freq);10661067try1068{1069if (nBits > 8 * (nCompressed - (ptr - compressed)))1070invalidNBits();10711072hufBuildDecTable (freq, im, iM, hdec);1073hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw);1074}1075catch (...)1076{1077hufFreeDecTable (hdec);1078throw;1079}10801081hufFreeDecTable (hdec);1082}108310841085} // namespace Imf108610871088