Пример #1
0
        /*
        *--------------------------------------------------------------
        *
        * HuffDecode --
        *
        * Taken from Figure F.16: extract next coded symbol from
        * input stream.  This should becode a macro.
        *
        * Results:
        * Next coded symbol
        *
        * Side effects:
        * Bitstream is parsed.
        *
        *--------------------------------------------------------------
        */
        int HuffDecodeNikon(BitPumpMSB bits)
        {
            int rv;
            int l, temp;
            int code, val;

            HuffmanTable* dctbl1 = &huff[0];

            bits.fill();
            code = bits.peekBitsNoFill(14);
            val = dctbl1.bigTable[code];
            if ((val & 0xff) != 0xff)
            {
                bits.skipBitsNoFill(val & 0xff);
                return val >> 8;
            }

            rv = 0;
            code = bits.peekByteNoFill();
            val = dctbl1.numbits[code];
            l = val & 15;
            if (l)
            {
                bits.skipBitsNoFill(l);
                rv = val >> 4;
            }
            else
            {
                bits.skipBits(8);
                l = 8;
                while (code > dctbl1.maxcode[l])
                {
                    temp = bits.getBitNoFill();
                    code = (code << 1) | temp;
                    l++;
                }

                if (l > 16)
                {
                    throw new Exception("Corrupt JPEG data: bad Huffman code:%u\n", l);
                }
                else
                {
                    rv = dctbl1.huffval[dctbl1.valptr[l] + ((int)(code - dctbl1.((code[l]))];
Пример #2
0
        void DecodeARW(ImageBinaryReader input, long w, long h)
        {
            BitPumpMSB bits = new BitPumpMSB(input);

            int sum = 0;

            for (long x = w; (x--) != 0;)
            {
                for (int y = 0; y < h + 1; y += 2)
                {
                    bits.Fill();
                    if (y == h)
                    {
                        y = 1;
                    }
                    int len = 4 - (int)bits.GetBits(2);
                    if (len == 3 && bits.GetBit() != 0)
                    {
                        len = 0;
                    }
                    if (len == 4)
                    {
                        while (len < 17 && bits.GetBit() == 0)
                        {
                            len++;
                        }
                    }
                    int diff = (int)bits.GetBits(len);
                    if (len != 0 && (diff & (1 << (len - 1))) == 0)
                    {
                        diff -= (1 << len) - 1;
                    }
                    sum += diff;
                    Debug.Assert((sum >> 12) == 0);
                    if (y < h)
                    {
                        rawImage.fullSize.rawView[x + y * rawImage.fullSize.dim.width] = (ushort)sum;
                    }
                }
            }
        }
Пример #3
0
        void DecompressNikon(ByteStream* metadata, UInt32 w, UInt32 h, UInt32 bitsPS, UInt32 offset, UInt32 size)
        {
            UInt32 v0 = metadata.getByte();
            UInt32 v1 = metadata.getByte();
            UInt32 huffSelect = 0;
            UInt32 split = 0;
            int[] pUp1 = new int[2];
            int[] pUp2 = new int[2];
            mUseBigtable = true;

            _RPT2(0, "Nef version v0:%u, v1:%u\n", v0, v1);

            if (v0 == 73 || v1 == 88)
                metadata.skipBytes(2110);

            if (v0 == 70) huffSelect = 2;
            if (bitsPS == 14) huffSelect += 3;

            pUp1[0] = metadata.getShort();
            pUp1[1] = metadata.getShort();
            pUp2[0] = metadata.getShort();
            pUp2[1] = metadata.getShort();

            int _max = 1 << bitsPS & 0x7fff;
            UInt32 step = 0;
            UInt32 csize = metadata.getShort();
            if (csize > 1)
                step = _max / (csize - 1);
            if (v0 == 68 && v1 == 32 && step > 0)
            {
                for (UInt32 i = 0; i < csize; i++)
                    curve[i * step] = metadata.getShort();
                for (int i = 0; i < _max; i++)
                    curve[i] = (curve[i - i % step] * (step - i % step) +
                                curve[i - i % step + step] * (i % step)) / step;
                metadata.setAbsoluteOffset(562);
                split = metadata.getShort();
            }
            else if (v0 != 70 && csize <= 0x4001)
            {
                for (UInt32 i = 0; i < csize; i++)
                {
                    curve[i] = metadata.getShort();
                }
                _max = csize;
            }
            initTable(huffSelect);

            mRaw.whitePoint = curve[_max - 1];
            mRaw.blackLevel = curve[0];
            if (!uncorrectedRawValues)
            {
                mRaw.setTable(curve, _max, true);
            }

            UInt32 x, y;
            BitPumpMSB bits = new BitPumpMSB(mFile, offset, size);
            byte* draw = mRaw.getData();
            UInt16* dest;
            UInt32 pitch = mRaw.pitch;

            int pLeft1 = 0;
            int pLeft2 = 0;
            UInt32 cw = w / 2;
            UInt32 random = bits.peekBits(24);
            //allow gcc to devirtualize the calls below
            RawImageDataU16[] rawdata = mRaw.get();
            for (y = 0; y < h; y++)
            {
                if (split && y == split)
                {
                    initTable(huffSelect + 1);
                }
                dest = (UInt16*)&draw[y * pitch];  // Adjust destination
                pUp1[y & 1] += HuffDecodeNikon(bits);
                pUp2[y & 1] += HuffDecodeNikon(bits);
                pLeft1 = pUp1[y & 1];
                pLeft2 = pUp2[y & 1];
                rawdata.setWithLookUp(clampbits(pLeft1, 15), (byte8*)dest++, &random);
                rawdata.setWithLookUp(clampbits(pLeft2, 15), (byte8*)dest++, &random);
                for (x = 1; x < cw; x++)
                {
                    bits.checkPos();
                    pLeft1 += HuffDecodeNikon(bits);
                    pLeft2 += HuffDecodeNikon(bits);
                    rawdata.setWithLookUp(clampbits(pLeft1, 15), (byte8*)dest++, &random);
                    rawdata.setWithLookUp(clampbits(pLeft2, 15), (byte8*)dest++, &random);
                }
            }

            if (uncorrectedRawValues)
            {
                mRaw.setTable(curve, _max, false);
            }
            else
            {
                mRaw.setTable(null);
            }
        }
Пример #4
0
        /* This is probably the slowest decoder of them all.
         * I cannot see any way to effectively speed up the prediction
         * phase, which is by far the slowest part of this algorithm.
         * Also there is no way to multithread this code, since prediction
         * is based on the output of all previous pixel (bar the first four)
         */
        private void DecodeCompressed(ImageBinaryReader s, uint width, uint height)
        {
            int  nbits;
            long left0, nw0, left1, nw1;
            long sign, low, high;

            long[] acarry0 = new long[3], acarry1 = new long[3];
            long   pred, diff;

            //uint pitch = rawImage.pitch;

            /* Build a table to quickly look up "high" value */
            byte[] bittable = new byte[4096];
            for (int i = 0; i < 4096; i++)
            {
                int b = i;
                for (high = 0; high < 12; high++)
                {
                    if (((b >> (11 - (int)high)) & 1) != 0)
                    {
                        break;
                    }
                }
                bittable[i] = (byte)Math.Min(12, high);
            }
            left0 = nw0 = left1 = nw1 = 0;
            s.ReadBytes(7);
            BitPumpMSB bits = new BitPumpMSB(s);

            for (int y = 0; y < height; y++)
            {
                var pos = y * rawImage.fullSize.UncroppedDim.width;
                acarry0 = new long[3];
                acarry1 = new long[3];
                bool y_border = y < 2;
                bool border   = true;
                for (int x = 0; x < width; x++)
                {
                    bits.Fill();
                    int i = 0;
                    if (acarry0[2] < 3)
                    {
                        i = 2;
                    }

                    for (nbits = 2 + i; acarry0[0] >> (nbits + i) != 0; nbits++)
                    {
                        ;
                    }

                    uint b = bits.PeekBits(15);
                    sign = (b >> 14) * -1;
                    low  = (b >> 12) & 3;
                    high = bittable[b & 4095];

                    // Skip bytes used above or read bits
                    if (high == 12)
                    {
                        bits.SkipBits(15);
                        high = bits.GetBits(16 - nbits) >> 1;
                    }
                    else
                    {
                        bits.SkipBits((int)high + 1 + 3);
                    }

                    acarry0[0] = (high << nbits) | bits.GetBits(nbits);
                    diff       = (acarry0[0] ^ sign) + acarry0[1];
                    acarry0[1] = (diff * 3 + acarry0[1]) >> 5;
                    acarry0[2] = acarry0[0] > 16 ? 0 : acarry0[2] + 1;

                    if (border)
                    {
                        if (y_border && x < 2)
                        {
                            pred = 0;
                        }
                        else if (y_border)
                        {
                            pred = left0;
                        }
                        else
                        {
                            pred = nw0 = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        }
                        rawImage.fullSize.rawView[pos + x] = (ushort)(pred + ((diff << 2) | low));
                        // Set predictor
                        left0 = rawImage.fullSize.rawView[pos + x];
                    }
                    else
                    {
                        // Have local variables for values used several tiles
                        // (having a "UInt16 *dst_up" that caches dest[-pitch+((int)x)] is actually slower, probably stack spill or aliasing)
                        int  up          = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        long leftMinusNw = left0 - nw0;
                        long upMinusNw   = up - nw0;
                        // Check if sign is different, and one is not zero
                        if (leftMinusNw * upMinusNw < 0)
                        {
                            if (Other_abs(leftMinusNw) > 32 || Other_abs(upMinusNw) > 32)
                            {
                                pred = left0 + upMinusNw;
                            }
                            else
                            {
                                pred = (left0 + up) >> 1;
                            }
                        }
                        else
                        {
                            pred = Other_abs(leftMinusNw) > Other_abs(upMinusNw) ? left0 : up;
                        }

                        rawImage.fullSize.rawView[pos + x] = (ushort)(pred + ((diff << 2) | low));
                        // Set predictors
                        left0 = rawImage.fullSize.rawView[pos + x];
                        nw0   = up;
                    }

                    // ODD PIXELS
                    x += 1;
                    bits.Fill();
                    i = 0;
                    if (acarry1[2] < 3)
                    {
                        i = 2;
                    }

                    for (nbits = 2 + i; acarry1[0] >> (nbits + i) != 0; nbits++)
                    {
                        ;
                    }
                    b    = bits.PeekBits(15);
                    sign = (b >> 14) * -1;
                    low  = (b >> 12) & 3;
                    high = bittable[b & 4095];

                    // Skip bytes used above or read bits
                    if (high == 12)
                    {
                        bits.SkipBits(15);
                        high = bits.GetBits(16 - nbits) >> 1;
                    }
                    else
                    {
                        bits.SkipBits((int)high + 1 + 3);
                    }

                    acarry1[0] = (high << nbits) | bits.GetBits(nbits);
                    diff       = (acarry1[0] ^ sign) + acarry1[1];
                    acarry1[1] = (diff * 3 + acarry1[1]) >> 5;
                    acarry1[2] = acarry1[0] > 16 ? 0 : acarry1[2] + 1;

                    if (border)
                    {
                        if (y_border && x < 2)
                        {
                            pred = 0;
                        }
                        else if (y_border)
                        {
                            pred = left1;
                        }
                        else
                        {
                            pred = nw1 = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        }
                        rawImage.fullSize.rawView[pos + x] = (ushort)(left1 = pred + ((diff << 2) | low));
                    }
                    else
                    {
                        int  up          = rawImage.fullSize.rawView[pos - rawImage.fullSize.UncroppedDim.width + x];
                        long leftminusNw = left1 - nw1;
                        long upminusNw   = up - nw1;

                        // Check if sign is different, and one is not zero
                        if (leftminusNw * upminusNw < 0)
                        {
                            if (Other_abs(leftminusNw) > 32 || Other_abs(upminusNw) > 32)
                            {
                                pred = left1 + upminusNw;
                            }
                            else
                            {
                                pred = (left1 + up) >> 1;
                            }
                        }
                        else
                        {
                            pred = Other_abs(leftminusNw) > Other_abs(upminusNw) ? left1 : up;
                        }

                        rawImage.fullSize.rawView[pos + x] = (ushort)(left1 = pred + ((diff << 2) | low));
                        nw1 = up;
                    }
                    border = y_border;
                }
            }
        }