コード例 #1
0
        public void DecodeDCFirst(JPEGBinaryReader stream, float[] dest)
        {
            int num = DCTable.Decode(stream);

            num        = HuffmanTable.Extend(stream.ReadBits(num), num);
            num        = (int)previousDC + num;
            previousDC = num;
            dest[0]    = num << successiveLow;
        }
コード例 #2
0
        public void DecodeDCFirst(JPEGBinaryReader stream, float[] dest)
        {
            //float[] datablock = new float[64];
            int s = DCTable.Decode(stream);
            int r = stream.ReadBits(s);

            s          = HuffmanTable.Extend(r, s);
            s          = (int)previousDC + s;
            previousDC = s;

            dest[0] = s << successiveLow;
        }
コード例 #3
0
        public void DecodeACFirst(JPEGBinaryReader stream, float[] zz)
        {
            if (stream.eob_run > 0)
            {
                stream.eob_run--;
                return;
            }

            for (int k = spectralStart; k <= spectralEnd; k++)
            {
                int s = ACTable.Decode(stream);
                int r = s >> 4;
                s &= 15;


                if (s != 0)
                {
                    k += r;

                    r     = (int)stream.ReadBits(s);
                    s     = (int)HuffmanTable.Extend(r, s);
                    zz[k] = s << successiveLow;
                }
                else
                {
                    if (r != 15)
                    {
                        stream.eob_run = 1 << r;

                        if (r != 0)
                        {
                            stream.eob_run += stream.ReadBits(r);
                        }

                        stream.eob_run--;

                        break;
                    }

                    k += 15;
                }
            }
        }
コード例 #4
0
        public void DecodeACFirst(JPEGBinaryReader stream, float[] zz)
        {
            if (stream.eob_run > 0)
            {
                stream.eob_run--;
                return;
            }
            int num = spectralStart;
            int num3;

            while (true)
            {
                if (num > spectralEnd)
                {
                    return;
                }
                int num2 = ACTable.Decode(stream);
                num3  = num2 >> 4;
                num2 &= 0xF;
                if (num2 != 0)
                {
                    num    += num3;
                    num3    = stream.ReadBits(num2);
                    num2    = HuffmanTable.Extend(num3, num2);
                    zz[num] = num2 << successiveLow;
                }
                else
                {
                    if (num3 != 15)
                    {
                        break;
                    }
                    num += 15;
                }
                num++;
            }
            stream.eob_run = 1 << num3;
            if (num3 != 0)
            {
                stream.eob_run += stream.ReadBits(num3);
            }
            stream.eob_run--;
        }
コード例 #5
0
        unsafe void DecodeScanLeft4Comps()
        {
            uint COMPS = 4;
            // First line
            HuffmanTable dctbl1 = huff[frame.ComponentInfo[0].dcTblNo];
            HuffmanTable dctbl2 = huff[frame.ComponentInfo[1].dcTblNo];
            HuffmanTable dctbl3 = huff[frame.ComponentInfo[2].dcTblNo];
            HuffmanTable dctbl4 = huff[frame.ComponentInfo[3].dcTblNo];

            if (CanonDoubleHeight)
            {
                frame.height *= 2;
                raw.raw.dim   = new Point2D(frame.width * 2, frame.height);
                raw.Init(false);
            }

            fixed(ushort *d = raw.raw.rawView)
            {
                //TODO remove this hack
                byte *draw = (byte *)d;

                //Prepare slices (for CR2)
                Int32 slices = slicesW.Count * (int)(frame.height - skipY);

                long[] offset = new long[(slices + 1)];

                UInt32 t_y   = 0;
                UInt32 t_x   = 0;
                UInt32 t_s   = 0;
                UInt32 slice = 0;

                for (slice = 0; slice < slices; slice++)
                {
                    offset[slice] = ((t_x + offX) * raw.Bpp + ((offY + t_y) * raw.pitch)) | (t_s << 28);
                    Debug.Assert((offset[slice] & 0x0fffffff) < raw.pitch * raw.raw.dim.height);
                    t_y++;
                    if (t_y == (frame.height - skipY))
                    {
                        t_y  = 0;
                        t_x += slicesW[(int)t_s++];
                    }
                }
                // We check the final position. If bad slice sizes are given we risk writing outside the image
                if ((offset[slices - 1] & 0x0fffffff) >= raw.pitch * raw.raw.dim.height)
                {
                    throw new RawDecoderException("decodeScanLeft: Last slice out of bounds");
                }
                offset[slices] = offset[slices - 1];        // Extra offset to avoid branch in loop.

                uint[] slice_width = new uint[slices];

                // This is divided by comps, since comps pixels are processed at the time
                for (Int32 i = 0; i < slicesW.Count; i++)
                {
                    slice_width[i] = slicesW[i] / COMPS;
                }

                if (skipX != 0)
                {
                    slice_width[slicesW.Count - 1] -= skipX;
                }

                // First pixels are obviously not predicted
                int     p1;
                int     p2;
                int     p3;
                int     p4;
                UInt16 *dest    = (UInt16 *)&draw[offset[0] & 0x0fffffff];
                UInt16 *predict = dest;

                p1 = (1 << (int)(frame.precision - Pt - 1)) + dctbl1.Decode();
                *dest++ = (ushort)p1;
                p2 = (1 << (int)(frame.precision - Pt - 1)) + dctbl2.Decode();
                *dest++ = (ushort)p2;
                p3 = (1 << (int)(frame.precision - Pt - 1)) + dctbl3.Decode();
                *dest++ = (ushort)p3;
                p4 = (1 << (int)(frame.precision - Pt - 1)) + dctbl4.Decode();
                *dest++ = (ushort)p4;

                slice = 1;
                UInt32 pixInSlice = slice_width[0] - 1;

                UInt32 cw = frame.width - skipX;
                UInt32 x  = 1;                           // Skip first pixels on first line.

                if (CanonDoubleHeight)
                {
                    skipY = frame.height >> 1;
                }

                for (UInt32 y = 0; y < (frame.height - skipY); y++)
                {
                    for (; x < cw; x++)
                    {
                        p1 += dctbl1.Decode();
                        *dest++ = (UInt16)p1;

                        p2 += dctbl2.Decode();
                        *dest++ = (UInt16)p2;

                        p3 += dctbl3.Decode();
                        *dest++ = (UInt16)p3;

                        p4 += dctbl4.Decode();
                        *dest++ = (UInt16)p4;

                        if (0 == --pixInSlice)
                        { // Next slice
                            if (slice > slices)
                            {
                                throw new RawDecoderException("decodeScanLeft: Ran out of slices");
                            }
                            long o = offset[slice++];
                            dest = (UInt16 *)&draw[o & 0x0fffffff];  // Adjust destination for next pixel
                            if ((o & 0x0fffffff) > raw.pitch * raw.raw.dim.height)
                            {
                                throw new RawDecoderException("decodeScanLeft: Offset out of bounds");
                            }
                            pixInSlice = slice_width[o >> 28];
                        }
                    }
                    if (skipX != 0)
                    {
                        for (UInt32 i = 0; i < skipX; i++)
                        {
                            dctbl1.Decode();
                            dctbl2.Decode();
                            dctbl3.Decode();
                            dctbl4.Decode();
                        }
                    }
                    p1      = predict[0]; // Predictors for next row
                    p2      = predict[1];
                    p3      = predict[2]; // Predictors for next row
                    p4      = predict[3];
                    predict = dest;       // Adjust destination for next prediction
                    x       = 0;
                }
            }
        }
コード例 #6
0
        unsafe void DecodeScanLeft2Comps()
        {
            uint COMPS = 2;

            Debug.Assert(slicesW.Count < 16);                 // We only have 4 bits for slice number.
            Debug.Assert(!(slicesW.Count > 1 && skipX != 0)); // Check if this is a valid state
            fixed(ushort *draw = raw.raw.rawView)
            {
                // First line
                HuffmanTable dctbl1 = huff[frame.ComponentInfo[0].dcTblNo];
                HuffmanTable dctbl2 = huff[frame.ComponentInfo[1].dcTblNo];

                //Prepare slices (for CR2)
                Int32 slices = slicesW.Count * (int)(frame.height - skipY);

                long[] offset = new long[(slices + 1)];

                UInt32 t_y   = 0;
                UInt32 t_x   = 0;
                UInt32 t_s   = 0;
                UInt32 slice = 0;
                UInt32 cw    = frame.width - skipX;

                for (slice = 0; slice < slices; slice++)
                {
                    offset[slice] = (t_x + offX + ((offY + t_y) * raw.raw.dim.width)) | (t_s << 28);
                    Debug.Assert((offset[slice] & 0x0fffffff) < raw.raw.dim.width * raw.raw.dim.height);
                    t_y++;
                    if (t_y == (frame.height - skipY))
                    {
                        t_y  = 0;
                        t_x += slicesW[(int)t_s++];
                    }
                }
                // We check the final position. If bad slice sizes are given we risk writing outside the image
                if ((offset[slices - 1] & 0x0fffffff) >= raw.raw.dim.width * raw.raw.dim.height)
                {
                    throw new RawDecoderException("decodeScanLeft: Last slice out of bounds");
                }
                offset[slices] = offset[slices - 1];        // Extra offset to avoid branch in loop.

                uint[] slice_width = new uint[slices];

                // This is divided by comps, since comps pixels are processed at the time
                for (Int32 i = 0; i < slicesW.Count; i++)
                {
                    slice_width[i] = slicesW[i] / COMPS;
                }

                if (skipX != 0)
                {
                    slice_width[slicesW.Count - 1] -= skipX;
                }

                // First pixels are obviously not predicted
                int     p1;
                int     p2;
                UInt16 *dest    = &draw[offset[0] & 0x0fffffff];
                UInt16 *predict = dest;

                p1 = (1 << (int)(frame.precision - Pt - 1)) + dctbl1.Decode();
                *dest++ = (ushort)p1;
                p2 = (1 << (int)(frame.precision - Pt - 1)) + dctbl2.Decode();
                *dest++ = (ushort)p2;

                slice = 1;                              // Always points to next slice
                UInt32 pixInSlice = slice_width[0] - 1; // Skip first pixel

                int x = 1;                              // Skip first pixels on first line.

                for (int y = 0; y < (frame.height - skipY); y++)
                {
                    for (; x < cw; x++)
                    {
                        p1 += dctbl1.Decode();
                        *dest++ = (ushort)p1;
                        //    Debug.Assert(p1 >= 0 && p1 < 65536);

                        p2 += dctbl2.Decode();
                        *dest++ = (ushort)p2;
                        //      Debug.Assert(p2 >= 0 && p2 < 65536);

                        if (0 == --pixInSlice)
                        { // Next slice
                            if (slice > slices)
                            {
                                throw new RawDecoderException("decodeScanLeft: Ran out of slices");
                            }
                            long o = offset[slice++];
                            dest = (UInt16 *)&draw[o & 0x0fffffff];  // Adjust destination for next pixel
                            if ((o & 0x0fffffff) > raw.pitch * raw.raw.dim.height)
                            {
                                throw new RawDecoderException("decodeScanLeft: Offset out of bounds");
                            }
                            pixInSlice = slice_width[o >> 28];
                        }
                    }

                    if (skipX != 0)
                    {
                        for (UInt32 i = 0; i < skipX; i++)
                        {
                            dctbl1.Decode();
                            dctbl2.Decode();
                        }
                    }

                    p1      = predict[0]; // Predictors for next row
                    p2      = predict[1];
                    predict = dest;       // Adjust destination for next prediction
                    x       = 0;
                }
            }
        }
コード例 #7
0
        unsafe void DecodeScanLeft4_2_2()
        {
            int COMPS = 3;

            Debug.Assert(slicesW.Count < 16);                 // We only have 4 bits for slice number.
            Debug.Assert(!(slicesW.Count > 1 && skipX != 0)); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[0].superH == 2); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[0].superV == 1); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[1].superH == 1); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[1].superV == 1); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[2].superH == 1); // Check if this is a valid state
            Debug.Assert(frame.ComponentInfo[2].superV == 1); // Check if this is a valid state
            Debug.Assert(frame.numComponents == COMPS);
            Debug.Assert(skipX == 0);
            HuffmanTable dctbl1 = huff[frame.ComponentInfo[0].dcTblNo];
            HuffmanTable dctbl2 = huff[frame.ComponentInfo[1].dcTblNo];
            HuffmanTable dctbl3 = huff[frame.ComponentInfo[2].dcTblNo];

            raw.metadata.Subsampling.width  = 2;
            raw.metadata.Subsampling.height = 1;

            UInt16 *predict;      // Prediction pointer

            fixed(ushort *d = raw.raw.rawView)
            {
                //TODO remove this hack
                byte *draw = (byte *)d;

                //Prepare slices (for CR2)
                Int32 slices = slicesW.Count * (int)(frame.height - skipY);

                long[] offset = new long[(slices + 1)];

                UInt32 t_y   = 0;
                UInt32 t_x   = 0;
                UInt32 t_s   = 0;
                UInt32 slice = 0;

                uint[] slice_width = new uint[slices];

                // This is divided by comps, since comps pixels are processed at the time
                for (int i = 0; i < slicesW.Count; i++)
                {
                    slice_width[i] = slicesW[i] / 2;
                }

                for (slice = 0; slice < slices; slice++)
                {
                    offset[slice] = ((t_x + offX) * raw.Bpp + ((offY + t_y) * raw.pitch)) | (t_s << 28);
                    Debug.Assert((offset[slice] & 0x0fffffff) < raw.pitch * raw.raw.dim.height);
                    t_y++;
                    if (t_y >= (frame.height - skipY))
                    {
                        t_y  = 0;
                        t_x += slice_width[t_s++];
                    }
                }
                if ((offset[slices - 1] & 0x0fffffff) >= raw.pitch * raw.raw.dim.height)
                {
                    throw new RawDecoderException("decodeScanLeft: Last slice out of bounds");
                }

                offset[slices] = offset[slices - 1];        // Extra offset to avoid branch in loop.

                if (skipX != 0)
                {
                    slice_width[slicesW.Count - 1] -= skipX;
                }

                // Predictors for components
                UInt16 *dest = (UInt16 *)&draw[offset[0] & 0x0fffffff];

                // Always points to next slice
                slice = 1;
                UInt32 pixInSlice = slice_width[0];

                // Initialize predictors and decode one group.
                UInt32 x = 0;
                int    p1;
                int    p2;
                int    p3;

                // First pixel is not predicted, all other are.
                p1 = (1 << (int)(frame.precision - Pt - 1)) + dctbl1.Decode();
                *dest = (ushort)p1;
                p1          = p1 + dctbl1.Decode();
                dest[COMPS] = (ushort)p1;
                predict     = dest;
                p2          = (1 << (int)(frame.precision - Pt - 1)) + dctbl2.Decode();
                dest[1]     = (ushort)p2;
                p3          = (1 << (int)(frame.precision - Pt - 1)) + dctbl3.Decode();
                dest[2]     = (ushort)p3;

                // Skip to next
                dest += COMPS * 2;

                x           = 2;
                pixInSlice -= 2;

                UInt32 cw = frame.width - skipX;

                for (int y = 0; y < (frame.height - skipY); y++)
                {
                    for (; x < cw; x += 2)
                    {
                        if (0 == pixInSlice)
                        { // Next slice
                            if (slice > slices)
                            {
                                throw new RawDecoderException("decodeScanLeft: Ran out of slices");
                            }
                            long o = offset[slice++];
                            dest = (UInt16 *)&draw[o & 0x0fffffff];  // Adjust destination for next pixel
                            if ((o & 0x0fffffff) > raw.pitch * raw.raw.dim.height)
                            {
                                throw new RawDecoderException("decodeScanLeft: Offset out of bounds");
                            }
                            pixInSlice = slice_width[o >> 28];

                            // If new are at the start of a new line, also update predictors.
                            if (x == 0)
                            {
                                predict = dest;
                            }
                        }
                        p1 += dctbl1.Decode();
                        *dest = (ushort)p1;
                        p1         += dctbl1.Decode();
                        dest[COMPS] = (ushort)p1;
                        p2          = p2 + dctbl2.Decode();
                        dest[1]     = (ushort)p2;
                        p3          = p3 + dctbl3.Decode();
                        dest[2]     = (ushort)p3;

                        dest       += COMPS * 2;
                        pixInSlice -= 2;
                    }

                    // Update predictors
                    p1      = predict[0];
                    p2      = predict[1];
                    p3      = predict[2];
                    predict = dest;
                    x       = 0;
                }
            }
        }