/** 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); } }); }
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; }