Пример #1
0
        /** Attempt to decode the image
         * A RawDecoderException will be thrown if the image cannot be decoded
         */
        public static void ReadUncompressedRaw(ImageBinaryReader input, Point2D size, Point2D offset, long inputPitch, int bitPerPixel, BitOrder order, Image <ushort> rawImage)
        {
            //uint outPitch = rawImage.pitch;
            var pos = new Point2D(size);//to avoid rewriting the image pos

            if (input.RemainingSize < (inputPitch * pos.height))
            {
                if (input.RemainingSize > inputPitch)
                {
                    pos.height = (uint)(input.RemainingSize / inputPitch - 1);
                    rawImage.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("Not enough data to decode a single line. Image file truncated.");
                }
            }
            if (bitPerPixel > 16)
            {
                throw new RawDecoderException("Unsupported bit depth");
            }

            int skipBits = (int)(inputPitch - pos.width * rawImage.fullSize.cpp * bitPerPixel / 8);  // Skip per line

            if (offset.height > rawImage.fullSize.dim.height)
            {
                throw new RawDecoderException("Invalid y offset");
            }
            if (offset.width + size.width > rawImage.fullSize.dim.width)
            {
                throw new RawDecoderException("Invalid x offset");
            }

            uint y = offset.height;

            if (bitPerPixel == 8)
            {
                Decode8BitRaw(input, pos, offset, rawImage);
                return;
            }
            else if (bitPerPixel == 10 && order == BitOrder.Jpeg && skipBits == 0)
            {
                //Optimisation for windows phone DNG
                Decode10BitRaw(input, pos, offset, rawImage);
                return;
            } /*
               * else if (bitPerPixel == 16 && Common.GetHostEndianness() == Endianness.Little)
               * {
               * Decode16BitRawUnpacked(input, pos, offset, rawImage);
               * return;
               * }
               * else if (bitPerPixel == 12 && pos.width == inputPitch * 8 / 12 && Common.GetHostEndianness() == Endianness.Little)
               * {
               * Decode12BitRaw(input, pos, offset, rawImage);
               * return;
               * }*/

            pos.width *= rawImage.fullSize.cpp;
            var off   = ((pos.width * bitPerPixel) / 8) + skipBits;
            var pumps = new BitPump[pos.height];

            //read the data
            switch (order)
            {
            case BitOrder.Jpeg:
                for (int i = 0; i < pos.height; i++)
                {
                    pumps[i] = new BitPumpMSB(input, input.BaseStream.Position, off);
                }
                break;

            case BitOrder.Jpeg16:
                for (int i = 0; i < pos.height; i++)
                {
                    pumps[i] = new BitPumpMSB16(input, input.BaseStream.Position, off);
                }
                break;

            case BitOrder.Jpeg32:
                for (int i = 0; i < pos.height; i++)
                {
                    pumps[i] = new BitPumpMSB32(input, input.BaseStream.Position, off);
                }
                break;

            default:
                for (int i = 0; i < pos.height; i++)
                {
                    pumps[i] = new BitPumpPlain(input, input.BaseStream.Position, off);
                }
                break;
            }
            Parallel.For(0, pos.height, i =>
            {
                long p = ((offset.height + i) * rawImage.fullSize.dim.width + offset.width) * rawImage.fullSize.cpp;
                for (uint x = 0; x < pos.width; x++)
                {
                    rawImage.fullSize.rawView[x + p] = (ushort)pumps[i].GetBits(bitPerPixel);
                }
            });
        }
Пример #2
0
        public void ParseSOS()
        {
            if (!frame.Initialized)
            {
                throw new RawDecoderException("Frame not yet initialized (SOF Marker not parsed)");
            }

            input.ReadInt16();
            uint soscps = input.ReadByte();

            if (frame.numComponents != soscps)
            {
                throw new RawDecoderException("Component number mismatch.");
            }

            for (int i = 0; i < frame.numComponents; i++)
            {
                uint cs    = input.ReadByte();
                uint count = 0;  // Find the correct component
                while (frame.ComponentInfo[count].componentId != cs)
                {
                    if (count >= frame.numComponents)
                    {
                        throw new RawDecoderException("Invalid Component Selector");
                    }
                    count++;
                }

                uint b1 = input.ReadByte();
                uint td = b1 >> 4;
                if (td > 3)
                {
                    throw new RawDecoderException("Invalid Huffman table selection");
                }
                if (!huff[td].Initialized)
                {
                    throw new RawDecoderException("Invalid Huffman table selection, not defined.");
                }

                if (count > 3)
                {
                    throw new RawDecoderException("Component count out of range");
                }

                frame.ComponentInfo[count].dcTblNo = td;
            }

            predictor = input.ReadByte();
            if (predictor > 7)
            {
                throw new RawDecoderException("Invalid predictor mode.");
            }

            input.ReadBytes(1); // Se + Ah Not used in LJPEG
            int b = input.ReadByte();

            Pt = b & 0xf;        // Point Transform

            bits = new BitPumpJPEG(input);
            for (int i = 0; i < huff.Length; i++)
            {
                huff[i].bitPump   = bits;
                huff[i].precision = frame.precision;
            }
            DecodeScan();
            input.Position = bits.Offset;
        }