bool ParseSegmentHeader(BitReader br) { m_segment_hdr.UseSegment = br.GetNextBit() != 0; if (m_segment_hdr.UseSegment) { m_segment_hdr.UpdateMap = br.GetNextBit() != 0; if (0 != br.GetNextBit()) { // update data m_segment_hdr.AbsoluteDelta = br.GetNextBit() != 0; for (int s = 0; s < NumMbSegments; ++s) { m_segment_hdr.Quantizer[s] = (byte)(br.GetNextBit() != 0 ? br.GetSignedValue (7) : 0); } for (int s = 0; s < NumMbSegments; ++s) { m_segment_hdr.FilterStrength[s] = (byte)(br.GetNextBit() != 0 ? br.GetSignedValue (6) : 0); } } if (m_segment_hdr.UpdateMap) { for (int s = 0; s < TreeProbs; ++s) { m_proba.Segments[s] = (byte)(br.GetNextBit() != 0 ? br.GetBits (8) : 255); } } } else { m_segment_hdr.UpdateMap = false; } return !br.Eof; }
void ParseQuant(BitReader br) { int base_q0 = br.GetBits (7); int dqy1_dc = br.GetNextBit() != 0 ? br.GetSignedValue (4) : 0; int dqy2_dc = br.GetNextBit() != 0 ? br.GetSignedValue (4) : 0; int dqy2_ac = br.GetNextBit() != 0 ? br.GetSignedValue (4) : 0; int dquv_dc = br.GetNextBit() != 0 ? br.GetSignedValue (4) : 0; int dquv_ac = br.GetNextBit() != 0 ? br.GetSignedValue (4) : 0; for (int i = 0; i < NumMbSegments; ++i) { int q; if (m_segment_hdr.UseSegment) { q = m_segment_hdr.Quantizer[i]; if (!m_segment_hdr.AbsoluteDelta) q += base_q0; } else if (i > 0) { m_dqm[i] = m_dqm[0]; continue; } else { q = base_q0; } var m = m_dqm[i]; m.y1_mat[0] = kDcTable[Clip (q + dqy1_dc, 127)]; m.y1_mat[1] = kAcTable[Clip (q + 0, 127)]; m.y2_mat[0] = kDcTable[Clip (q + dqy2_dc, 127)] * 2; // For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16. // The smallest precision for that is '(x*6349) >> 12' but 16 is a good // word size. m.y2_mat[1] = (kAcTable[Clip (q + dqy2_ac, 127)] * 101581) >> 16; if (m.y2_mat[1] < 8) m.y2_mat[1] = 8; m.uv_mat[0] = kDcTable[Clip (q + dquv_dc, 117)]; m.uv_mat[1] = kAcTable[Clip (q + dquv_ac, 127)]; m.uv_quant = q + dquv_ac; // for dithering strength evaluation } }
bool ParseFilterHeader(BitReader br) { m_filter_hdr.Simple = br.GetNextBit() != 0; m_filter_hdr.Level = br.GetBits (6); m_filter_hdr.Sharpness = br.GetBits (3); m_filter_hdr.UseLfDelta = br.GetNextBit() != 0; if (m_filter_hdr.UseLfDelta) { if (0 != br.GetNextBit()) { // update lf-delta? for (int i = 0; i < NumRefLfDeltas; ++i) { if (0 != br.GetNextBit()) m_filter_hdr.RefLfDelta[i] = br.GetSignedValue (6); } for (int i = 0; i < NumModeLfDeltas; ++i) { if (0 != br.GetNextBit()) m_filter_hdr.ModeLfDelta[i] = br.GetSignedValue (6); } } } m_filter_type = (0 == m_filter_hdr.Level) ? 0 : m_filter_hdr.Simple ? 1 : 2; return !br.Eof; }
void ParseProba(BitReader br) { for (int t = 0; t < NumTypes; ++t) { for (int b = 0; b < NumBands; ++b) for (int c = 0; c < NumCtx; ++c) for (int p = 0; p < NumProbas; ++p) { int v = br.GetBit (CoeffsUpdateProba[t,b,c,p]) != 0 ? br.GetBits (8) : CoeffsProba0[t,b,c,p]; m_proba.Bands[t,b].Probas[c][p] = (byte)v; } for (int b = 0; b < 16 + 1; ++b) { m_proba.BandsPtr[t][b] = m_proba.Bands[t,kBands[b]]; } } m_use_skip_proba = br.GetNextBit() != 0; if (m_use_skip_proba) m_skip_p = br.GetBits (8); }
void GetHeaders() { int chunk_size = m_info.DataSize; int bits = ReadInt24(); chunk_size -= 3; m_frame_header.KeyFrame = 0 == (bits & 1); m_frame_header.Profile = (bits >> 1) & 7; m_frame_header.Show = 0 != (bits & (1u << 4)); m_frame_header.PartitionLength = bits >> 5; if (m_frame_header.Profile > 3) throw new InvalidFormatException ("Incorrect keyframe parameters."); if (!m_frame_header.Show) throw new InvalidFormatException ("Frame not displayable."); if (m_frame_header.KeyFrame) { // Paragraph 9.2 if (!CheckSignature()) throw new InvalidFormatException ("Bad code word"); ushort w = m_input.ReadUInt16(); ushort h = m_input.ReadUInt16(); m_pic_hdr.Width = (ushort)(w & 0x3fff); m_pic_hdr.XScale = (byte)(w >> 14); // ratio: 1, 5/4 5/3 or 2 m_pic_hdr.Height = (ushort)(h & 0x3fff); m_pic_hdr.YScale = (byte)(h >> 14); chunk_size -= 7; mb_w_ = (m_pic_hdr.Width + 15) >> 4; mb_h_ = (m_pic_hdr.Height + 15) >> 4; // Setup default output area (can be later modified during m_io.setup()) m_io.width = m_pic_hdr.Width; m_io.height = m_pic_hdr.Height; m_io.mb_w = m_io.width; m_io.mb_h = m_io.height; m_proba.Reset(); m_segment_hdr.Reset(); } if (m_frame_header.PartitionLength > chunk_size) throw new InvalidFormatException ("bad partition length"); m_br = new BitReader (m_input, m_frame_header.PartitionLength); chunk_size -= m_frame_header.PartitionLength; if (m_frame_header.KeyFrame) { m_pic_hdr.Colorspace = (byte)m_br.GetNextBit(); m_pic_hdr.ClampType = (byte)m_br.GetNextBit(); } if (!ParseSegmentHeader (m_br)) throw new InvalidFormatException ("Cannot parse segment header"); // Filter specs if (!ParseFilterHeader (m_br)) throw new InvalidFormatException ("Cannot parse filter header"); if (!ParsePartitions (m_br, chunk_size)) throw new InvalidFormatException ("Cannot parse partitions"); for (int i = 0; i < m_dqm.Length; ++i) m_dqm[i] = new QuantMatrix(); // quantizer change ParseQuant (m_br); // Frame buffer marking if (!m_frame_header.KeyFrame) throw new InvalidFormatException ("Not a key frame"); m_br.GetNextBit(); // ignore the value of update_proba_ ParseProba (m_br); }