/src/main/Silverlight/WallpaperCreatorForSamsungPhone/WallpaperCreatorForSamsungPhone/FJCore/Decoder/HuffmanTable.cs
http://s5230wallpapercreator.googlecode.com/ · C# · 487 lines · 372 code · 68 blank · 47 comment · 68 complexity · cf250d639269cda8367b0cfc79e6a950 MD5 · raw file
- /// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
- /// Under the MIT License, details: License.txt.
-
- // Partially derives from a Java encoder, JpegEncoder.java by James R Weeks.
- // Implements Baseline JPEG Encoding http://www.opennet.ru/docs/formats/jpeg.txt
-
- using System;
-
- using FluxJpeg.Core.IO;
- using System.IO;
- using System.Collections.Generic;
-
- namespace FluxJpeg.Core
- {
- internal class HuffmanTable
- {
- public static int HUFFMAN_MAX_TABLES = 4;
-
- private short[] huffcode = new short[256];
- private short[] huffsize = new short[256];
- private short[] valptr = new short[16];
- private short[] mincode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1,-1};
- private short[] maxcode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
-
- private short[] huffval;
- private short[] bits;
-
- int bufferPutBits, bufferPutBuffer;
- internal int ImageHeight;
- internal int ImageWidth;
- internal int[,] DC_matrix0;
- internal int[,] AC_matrix0;
- internal int[,] DC_matrix1;
- internal int[,] AC_matrix1;
- internal int[][,] DC_matrix;
- internal int[][,] AC_matrix;
- internal int NumOfDCTables;
- internal int NumOfACTables;
-
- public List<short[]> bitsList;
- public List<short[]> val;
-
-
- public static byte JPEG_DC_TABLE = 0;
- public static byte JPEG_AC_TABLE = 1;
-
- private short lastk = 0;
-
- internal HuffmanTable(JpegHuffmanTable table)
- {
- if (table != null)
- {
- huffval = table.Values;
- bits = table.Lengths;
-
- GenerateSizeTable();
- GenerateCodeTable();
- GenerateDecoderTables();
- }
- else
- {
- // Encode initialization
-
- bitsList = new List<short[]>();
- bitsList.Add(JpegHuffmanTable.StdDCLuminance.Lengths);
- bitsList.Add(JpegHuffmanTable.StdACLuminance.Lengths);
- bitsList.Add(JpegHuffmanTable.StdDCChrominance.Lengths);
- bitsList.Add(JpegHuffmanTable.StdACChrominance.Lengths);
-
- val = new List<short[]>();
- val.Add(JpegHuffmanTable.StdDCLuminance.Values);
- val.Add(JpegHuffmanTable.StdACLuminance.Values);
- val.Add(JpegHuffmanTable.StdDCChrominance.Values);
- val.Add(JpegHuffmanTable.StdACChrominance.Values);
-
- initHuf();
- }
- }
-
- /// <summary>See Figure C.1</summary>
- private void GenerateSizeTable()
- {
- short index = 0;
- for (short i = 0; i < bits.Length; i++)
- {
- for (short j = 0; j < bits[i]; j++)
- {
- huffsize[index] = (short)(i + 1);
- index++;
- }
- }
- lastk = index;
- }
-
- /// <summary>See Figure C.2</summary>
- private void GenerateCodeTable()
- {
- short k = 0;
- short si = huffsize[0];
- short code = 0;
- for (short i = 0; i < huffsize.Length; i++)
- {
- while (huffsize[k] == si)
- {
- huffcode[k] = code;
- code++;
- k++;
- }
- code <<= 1;
- si++;
- }
- }
-
- /// <summary>See figure F.15</summary>
- private void GenerateDecoderTables()
- {
- short bitcount = 0;
- for (int i = 0; i < 16; i++)
- {
- if (bits[i] != 0)
- valptr[i] = bitcount;
- for (int j = 0; j < bits[i]; j++)
- {
- if (huffcode[j + bitcount] < mincode[i] || mincode[i] == -1)
- mincode[i] = huffcode[j + bitcount];
-
- if (huffcode[j + bitcount] > maxcode[i])
- maxcode[i] = huffcode[j + bitcount];
- }
- if (mincode[i] != -1)
- valptr[i] = (short)(valptr[i] - mincode[i]);
- bitcount += bits[i];
- }
- }
-
- /// <summary>Figure F.12</summary>
- public static int Extend(int diff, int t)
- {
- // here we use bitshift to implement 2^ ...
- // NOTE: Math.Pow returns 0 for negative powers, which occassionally happen here!
-
- int Vt = 1 << t - 1;
- // WAS: int Vt = (int)Math.Pow(2, (t - 1));
-
- if (diff < Vt)
- {
- Vt = (-1 << t) + 1;
- diff = diff + Vt;
- }
- return diff;
- }
-
- /// <summary>Figure F.16 - Reads the huffman code bit-by-bit.</summary>
- public int Decode(JPEGBinaryReader JPEGStream)
- {
- int i = 0;
- short code = (short)JPEGStream.ReadBits(1);
- while (code > maxcode[i])
- {
- i++;
- code <<= 1;
- code |= (short)JPEGStream.ReadBits(1);
- }
- int val = huffval[code + (valptr[i])];
- if (val < 0)
- val = 256 + val;
- return val;
- }
-
- /// <summary>
- /// HuffmanBlockEncoder run length encodes and Huffman encodes the quantized data.
- /// </summary>
- internal void HuffmanBlockEncoder(Stream outStream, int[] zigzag, int prec, int DCcode, int ACcode)
- {
- int temp, temp2, nbits, k, r, i;
-
- NumOfDCTables = 2;
- NumOfACTables = 2;
-
- // The DC portion
-
- temp = temp2 = zigzag[0] - prec;
- if (temp < 0)
- {
- temp = -temp;
- temp2--;
- }
- nbits = 0;
- while (temp != 0)
- {
- nbits++;
- temp >>= 1;
- }
- // if (nbits > 11) nbits = 11;
- bufferIt(outStream,
- DC_matrix[DCcode][nbits, 0],
- DC_matrix[DCcode][nbits, 1]);
-
- // The arguments in bufferIt are code and size.
- if (nbits != 0)
- {
- bufferIt(outStream, temp2, nbits);
- }
-
- // The AC portion
-
- r = 0;
-
- for (k = 1; k < 64; k++)
- {
- if ((temp = zigzag[ ZigZag.ZigZagMap[k] ]) == 0)
- {
- r++;
- }
- else
- {
- while (r > 15)
- {
- bufferIt(outStream,
- AC_matrix[ACcode][0xF0, 0],
- AC_matrix[ACcode][0xF0, 1]);
-
- r -= 16;
- }
- temp2 = temp;
- if (temp < 0)
- {
- temp = -temp;
- temp2--;
- }
- nbits = 1;
- while ((temp >>= 1) != 0)
- {
- nbits++;
- }
- i = (r << 4) + nbits;
- bufferIt(outStream,
- AC_matrix[ACcode][i, 0],
- AC_matrix[ACcode][i, 1]);
- bufferIt(outStream, temp2, nbits);
-
- r = 0;
- }
- }
-
- if (r > 0)
- {
- bufferIt(outStream,
- AC_matrix[ACcode][0, 0],
- AC_matrix[ACcode][0, 1]);
- }
- }
-
- /// <summary>
- /// Uses an integer long (32 bits) buffer to store the Huffman encoded bits
- /// and sends them to outStream by the byte.
- /// </summary>
- void bufferIt(Stream outStream, int code, int size)
- {
- int PutBuffer = code;
- int PutBits = bufferPutBits;
-
- PutBuffer &= (1 << size) - 1;
- PutBits += size;
- PutBuffer <<= 24 - PutBits;
- PutBuffer |= bufferPutBuffer;
-
- while (PutBits >= 8)
- {
- int c = ((PutBuffer >> 16) & 0xFF);
- outStream.WriteByte((byte)c);
-
- // FF must be escaped
- if (c == 0xFF) outStream.WriteByte(0);
-
- PutBuffer <<= 8;
- PutBits -= 8;
- }
- bufferPutBuffer = PutBuffer;
- bufferPutBits = PutBits;
-
- }
-
- public void FlushBuffer(Stream outStream)
- {
- int PutBuffer = bufferPutBuffer;
- int PutBits = bufferPutBits;
- while (PutBits >= 8)
- {
- int c = ((PutBuffer >> 16) & 0xFF);
- outStream.WriteByte((byte)c);
-
- // FF must be escaped
- if (c == 0xFF) outStream.WriteByte(0);
-
- PutBuffer <<= 8;
- PutBits -= 8;
- }
- if (PutBits > 0)
- {
- int c = ((PutBuffer >> 16) & 0xFF);
- outStream.WriteByte((byte)c);
- }
- }
-
-
- /// <summary>
- /// Initialisation of the Huffman codes for Luminance and Chrominance.
- /// This code results in the same tables created in the IJG Jpeg-6a
- /// library.
- /// </summary>
- public void initHuf()
- {
- DC_matrix0 = new int[12, 2];
- DC_matrix1 = new int[12, 2];
- AC_matrix0 = new int[255, 2];
- AC_matrix1 = new int[255, 2];
- DC_matrix = new int[2][,];
- AC_matrix = new int[2][,];
- int p, l, i, lastp, si, code;
- int[] huffsize = new int[257];
- int[] huffcode = new int[257];
-
- short[] bitsDCchrominance = JpegHuffmanTable.StdDCChrominance.Lengths;
- short[] bitsACchrominance = JpegHuffmanTable.StdACChrominance.Lengths;
- short[] bitsDCluminance = JpegHuffmanTable.StdDCLuminance.Lengths;
- short[] bitsACluminance = JpegHuffmanTable.StdACLuminance.Lengths;
-
-
- short[] valDCchrominance = JpegHuffmanTable.StdDCChrominance.Values;
- short[] valACchrominance = JpegHuffmanTable.StdACChrominance.Values;
- short[] valDCluminance = JpegHuffmanTable.StdDCLuminance.Values;
- short[] valACluminance = JpegHuffmanTable.StdACLuminance.Values;
-
-
- /*
- * init of the DC values for the chrominance
- * [,0] is the code [,1] is the number of bit
- */
-
- p = 0;
- for (l = 0; l < 16; l++)
- {
- for (i = 1; i <= bitsDCchrominance[l]; i++)
- {
- huffsize[p++] = l+1;
- }
- }
-
- huffsize[p] = 0;
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p] != 0)
- {
- while (huffsize[p] == si)
- {
- huffcode[p++] = code;
- code++;
- }
- code <<= 1;
- si++;
- }
-
- for (p = 0; p < lastp; p++)
- {
- DC_matrix1[valDCchrominance[p], 0] = huffcode[p];
- DC_matrix1[valDCchrominance[p], 1] = huffsize[p];
- }
-
- /*
- * Init of the AC hufmann code for the chrominance
- * matrix [,,0] is the code & matrix[,,1] is the number of bit needed
- */
-
- p = 0;
- for (l = 0; l < 16; l++)
- {
- for (i = 1; i <= bitsACchrominance[l]; i++)
- {
- huffsize[p++] = l+1;
- }
- }
- huffsize[p] = 0;
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p] != 0)
- {
- while (huffsize[p] == si)
- {
- huffcode[p++] = code;
- code++;
- }
- code <<= 1;
- si++;
- }
-
- for (p = 0; p < lastp; p++)
- {
- AC_matrix1[valACchrominance[p], 0] = huffcode[p];
- AC_matrix1[valACchrominance[p], 1] = huffsize[p];
- }
-
- /*
- * init of the DC values for the luminance
- * [,0] is the code [,1] is the number of bit
- */
- p = 0;
- for (l = 0; l < 16; l++)
- {
- for (i = 1; i <= bitsDCluminance[l]; i++)
- {
- huffsize[p++] = l+1;
- }
- }
- huffsize[p] = 0;
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p] != 0)
- {
- while (huffsize[p] == si)
- {
- huffcode[p++] = code;
- code++;
- }
- code <<= 1;
- si++;
- }
-
- for (p = 0; p < lastp; p++)
- {
- DC_matrix0[valDCluminance[p], 0] = huffcode[p];
- DC_matrix0[valDCluminance[p], 1] = huffsize[p];
- }
-
- /*
- * Init of the AC hufmann code for luminance
- * matrix [,,0] is the code & matrix[,,1] is the number of bit
- */
-
- p = 0;
- for (l = 0; l < 16; l++)
- {
- for (i = 1; i <= bitsACluminance[l]; i++)
- {
- huffsize[p++] = l+1;
- }
- }
- huffsize[p] = 0;
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p] != 0)
- {
- while (huffsize[p] == si)
- {
- huffcode[p++] = code;
- code++;
- }
- code <<= 1;
- si++;
- }
- for (int q = 0; q < lastp; q++)
- {
- AC_matrix0[valACluminance[q], 0] = huffcode[q];
- AC_matrix0[valACluminance[q], 1] = huffsize[q];
- }
-
- DC_matrix[0] = DC_matrix0;
- DC_matrix[1] = DC_matrix1;
- AC_matrix[0] = AC_matrix0;
- AC_matrix[1] = AC_matrix1;
- }
-
-
- }
- }