Exemplo n.º 1
0
        public void Decode12BitRawBE(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < ((w * 12 / 8) * h))
            {
                if ((UInt32)input.getRemainSize() > (w * 12 / 8))
                {
                    h = (uint)(input.getRemainSize() / (w * 12 / 8) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }
            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[y * pitch + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                }
            }
        }
Exemplo n.º 2
0
        public void Decode12BitRawUnpacked(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < w * h * 2)
            {
                if ((UInt32)input.getRemainSize() > w * 2)
                {
                    h = (uint)(input.getRemainSize() / (w * 2) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }
            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 1)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)(((g2 << 8) | g1) >> 4);
                }
            }
        }
Exemplo n.º 3
0
        public void Decode12BitRawBEInterlaced(TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            if (input.getRemainSize() < ((w * 12 / 8) * h))
            {
                if ((UInt32)input.getRemainSize() > (w * 12 / 8))
                {
                    h = (uint)(input.getRemainSize() / (w * 12 / 8) - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 half = (h + 1) >> 1;
            UInt32 y    = 0;

            for (UInt32 row = 0; row < h; row++)
            {
                y = row % half * 2 + row / half;
                if (y == 1)
                {
                    // The second field starts at a 2048 byte aligment
                    UInt32 offset = ((half * w * 3 / 2 >> 11) + 1) << 11;
                    if (offset > input.getRemainSize())
                    {
                        throw new IOException("Decode12BitSplitRaw: Trying to jump to invalid offset " + offset);
                    }
                    input.Position = offset;
                }
                for (UInt32 x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[y * pitch + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[y * pitch + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                }
            }
        }
Exemplo n.º 4
0
        public void Decode12BitRawBEWithControl(ref TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            if (w < 2)
            {
                throw new IOException("Are you mad? 1 pixel wide raw images are no fun");
            }

            UInt32 pitch = mRaw.pitch;

            // Calulate expected bytes per line.
            UInt32 perline = (w * 12 / 8);

            // Add skips every 10 pixels
            perline += ((w + 2) / 10);

            // If file is too short, only decode as many lines as we have
            if (input.getRemainSize() < (perline * h))
            {
                if ((UInt32)input.getRemainSize() > perline)
                {
                    h = (uint)(input.getRemainSize() / perline - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("Decode12BitRawBEWithControl: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 x;

            for (UInt32 y = 0; y < h; y++)
            {
                for (x = 0; x < w; x += 2)
                {
                    UInt32 g1 = input.ReadByte();
                    UInt32 g2 = input.ReadByte();
                    mRaw.rawData[(y * pitch) + x] = (ushort)((g1 << 4) | (g2 >> 4));
                    UInt32 g3 = input.ReadByte();
                    mRaw.rawData[(y * pitch) + x + 1] = (ushort)(((g2 & 0x0f) << 8) | g3);
                    if ((x % 10) == 8)
                    {
                        input.Position++;
                    }
                }
            }
        }
Exemplo n.º 5
0
        public void Decode8BitRaw(ref TIFFBinaryReader input, UInt32 w, UInt32 h)
        {
            ushort[] data  = mRaw.rawData;
            UInt32   pitch = mRaw.pitch;

            if (input.getRemainSize() < w * h)
            {
                if ((UInt32)input.getRemainSize() > w)
                {
                    h = (uint)(input.getRemainSize() / w - 1);
                    mRaw.errors.Add("Image truncated (file is too short)");
                }
                else
                {
                    throw new IOException("Decode8BitRaw: Not enough data to decode a single line. Image file truncated.");
                }
            }

            UInt32 random = 0;

            for (UInt32 y = 0; y < h; y++)
            {
                for (UInt32 x = 0; x < w; x += 1)
                {
                    if (uncorrectedRawValues)
                    {
                        mRaw.rawData[(y * pitch) + x] = input.ReadByte();
                    }
                    else
                    {
                        mRaw.setWithLookUp(input.ReadByte(), ref mRaw.rawData, x, ref random);
                        input.Position++;
                    }
                }
            }
        }
Exemplo n.º 6
0
        public void DecompressNikon(TIFFBinaryReader metadata, UInt32 w, UInt32 h, UInt32 bitsPS, UInt32 offset, UInt32 size)
        {
            metadata.Position = 0;
            UInt32 v0         = metadata.ReadByte();
            UInt32 v1         = metadata.ReadByte();
            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.ReadBytes(2110);
            }

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

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

            int    _max  = 1 << (int)bitsPS & 0x7fff;
            UInt32 step  = 0;
            UInt32 csize = metadata.ReadUInt16();

            if (csize > 1)
            {
                step = (uint)_max / (csize - 1);
            }
            if (v0 == 68 && v1 == 32 && step > 0)
            {
                for (UInt32 i = 0; i < csize; i++)
                {
                    curve[i * step] = (ushort)metadata.ReadInt16();
                }
                for (int i = 0; i < _max; i++)
                {
                    curve[i] = (ushort)((curve[i - i % step] * (step - i % step) + curve[i - i % step + step] * (i % step)) / step);
                }
                metadata.Position = (562);
                split             = metadata.ReadUInt16();
            }
            else if (v0 != 70 && csize <= 0x4001)
            {
                for (UInt32 i = 0; i < csize; i++)
                {
                    curve[i] = metadata.ReadUInt16();
                }
                _max = (int)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(ref input, offset, size);
            UInt32     pitch = w;

            int    pLeft1 = 0;
            int    pLeft2 = 0;
            UInt32 cw     = w / 2;
            UInt32 random = bits.peekBits(24);

            for (y = 0; y < h; y++)
            {
                if (split != 0 && (y == split))
                {
                    initTable(huffSelect + 1);
                }
                pUp1[y & 1] += HuffDecodeNikon(bits);
                pUp2[y & 1] += HuffDecodeNikon(bits);
                pLeft1       = pUp1[y & 1];
                pLeft2       = pUp2[y & 1];
                uint dest = y * pitch;
                mRaw.setWithLookUp((ushort)Common.clampbits(pLeft1, 15), ref mRaw.rawData, dest++, ref random);
                mRaw.setWithLookUp((ushort)Common.clampbits(pLeft2, 15), ref mRaw.rawData, dest++, ref random);
                for (x = 1; x < cw; x++)
                {
                    bits.checkPos();
                    pLeft1 += HuffDecodeNikon(bits);
                    pLeft2 += HuffDecodeNikon(bits);
                    mRaw.setWithLookUp((ushort)Common.clampbits(pLeft1, 15), ref mRaw.rawData, dest++, ref random);
                    mRaw.setWithLookUp((ushort)Common.clampbits(pLeft2, 15), ref mRaw.rawData, dest++, ref random);
                }
            }

            if (uncorrectedRawValues)
            {
                mRaw.setTable(curve, _max, false);
            }
            else
            {
                mRaw.table = (null);
            }
        }
Exemplo n.º 7
0
        public IFD(TIFFBinaryReader fileStream, uint offset, Endianness endian)
        {
            this.endian         = endian;
            fileStream.Position = offset;
            tagNumber           = fileStream.ReadUInt16();
            tags = new Dictionary <TagType, Tag>();

            for (int i = 0; i < tagNumber; i++)
            {
                Tag temp = new Tag();
                temp.tagId = (TagType)fileStream.ReadUInt16();
                //add the displayname
                temp.displayName = null;

                temp.dataType  = (TiffDataType)fileStream.ReadUInt16();
                temp.dataCount = fileStream.ReadUInt32();

                //IF makernote, do not parse data
                //if (temp.tagId == TagType.MAKERNOTE || temp.tagId == TagType.MAKERNOTE_ALT) temp.dataCount = 0;

                temp.dataOffset = 0;
                if (((temp.dataCount * temp.getTypeSize(temp.dataType) > 4)))
                {
                    temp.dataOffset = fileStream.ReadUInt32();
                }

                //Get the tag data
                temp.data = new Object[temp.dataCount];
                long firstPosition = fileStream.Position;
                if (temp.dataOffset > 1)
                {
                    fileStream.Position = temp.dataOffset;
                    //todo check if correct
                }

                if (temp.tagId != TagType.MAKERNOTE && temp.tagId != TagType.MAKERNOTE_ALT)
                {
                    for (int j = 0; j < temp.dataCount; j++)
                    {
                        switch (temp.dataType)
                        {
                        case TiffDataType.BYTE:
                        case TiffDataType.UNDEFINED:
                        case TiffDataType.ASCII:
                        case TiffDataType.OFFSET:
                            temp.data[j] = fileStream.ReadByte();
                            break;

                        case TiffDataType.SHORT:
                            temp.data[j] = fileStream.ReadUInt16();
                            break;

                        case TiffDataType.LONG:
                            temp.data[j] = fileStream.ReadUInt32();
                            break;

                        case TiffDataType.RATIONAL:
                            temp.data[j] = fileStream.ReadDouble();
                            break;

                        case TiffDataType.SBYTE:
                            temp.data[j] = fileStream.ReadSByte();
                            break;

                        case TiffDataType.SSHORT:
                            temp.data[j] = fileStream.ReadInt16();
                            //if (temp.dataOffset == 0 && temp.dataCount == 1) fileStream.ReadInt16();
                            break;

                        case TiffDataType.SLONG:
                            temp.data[j] = fileStream.ReadInt32();
                            break;

                        case TiffDataType.SRATIONAL:
                            //Because the nikonmakernote is broken with the tag 0x19 wich is double but offset of zero.
                            //TODO remove this Fix
                            if (temp.dataOffset == 0)
                            {
                                temp.data[j] = .0;
                            }
                            else
                            {
                                temp.data[j] = fileStream.ReadDouble();
                            }
                            break;

                        case TiffDataType.FLOAT:
                            temp.data[j] = fileStream.ReadSingle();
                            break;

                        case TiffDataType.DOUBLE:
                            temp.data[j] = fileStream.ReadDouble();
                            break;
                        }
                    }
                }//Special tag
                switch (temp.tagId)
                {
                case TagType.DNGPRIVATEDATA:
                {
                    try
                    {
                        IFD maker_ifd = parseDngPrivateData(temp);
                        if (maker_ifd != null)
                        {
                            subIFD.Add(maker_ifd);
                        }
                        temp.data = null;
                    }
                    catch (TiffParserException)
                    {         // Unparsable private data are added as entries
                    }
                    catch (IOException)
                    {         // Unparsable private data are added as entries
                    }
                }
                break;

                case TagType.MAKERNOTE:
                case TagType.MAKERNOTE_ALT:
                {
                    try
                    {
                        //save current position
                        long pos       = fileStream.Position;
                        IFD  makernote = parseMakerNote(fileStream, temp.dataOffset, endian);
                        if (makernote != null)
                        {
                            subIFD.Add(makernote);
                        }

                        //correct here
                        fileStream.BaseStream.Position = pos;
                        //return to current position
                    }
                    catch (TiffParserException)
                    {         // Unparsable makernotes are added as entries
                    }
                    catch (IOException)
                    {         // Unparsable makernotes are added as entries
                    }
                }
                break;

                case TagType.FUJI_RAW_IFD:
                    if (temp.dataType == TiffDataType.OFFSET)     // FUJI - correct type
                    {
                        temp.dataType = TiffDataType.LONG;
                    }
                    goto case TagType.SUBIFDS;

                case TagType.SUBIFDS:
                case TagType.EXIFIFDPOINTER:
                case TagType.NIKONTHUMB:
                    long p = fileStream.Position;
                    try
                    {
                        for (Int32 k = 0; k < temp.dataCount; k++)
                        {
                            subIFD.Add(new IFD(fileStream, Convert.ToUInt32(temp.data[k]), endian, depth));
                        }
                    }
                    catch (TiffParserException)
                    {     // Unparsable subifds are added as entries
                    }
                    catch (IOException)
                    {     // Unparsable subifds are added as entries
                    }
                    fileStream.BaseStream.Position = p;
                    break;
                }
                //transform data ToString
                if (temp.dataType == TiffDataType.ASCII)
                {
                    //remove \0 if any
                    if ((byte)temp.data[temp.dataCount - 1] == 0)
                    {
                        temp.data[temp.dataCount - 1] = (byte)' ';
                    }
                    string t = Encoding.ASCII.GetString(temp.data.Cast <byte>().ToArray());
                    temp.data    = new Object[1];
                    temp.data[0] = t;
                }

                if (temp.dataOffset > 1)
                {
                    fileStream.BaseStream.Position = firstPosition;
                }
                else if (temp.dataOffset == 0)
                {
                    int k = (int)temp.dataCount * temp.getTypeSize(temp.dataType);
                    if (k < 4)
                    {
                        fileStream.ReadBytes(4 - k);
                    }
                }

                /*else
                 * {
                 *  temp.dataCount = 0;
                 *  temp.data = null;
                 * }*/
                if (!tags.ContainsKey(temp.tagId))
                {
                    tags.Add(temp.tagId, temp);
                }
                else
                {
                    Debug.WriteLine("tags already exist");
                }
            }
            nextOffset = fileStream.ReadUInt16();
        }
Exemplo n.º 8
0
        public void parseSOF(SOFInfo sof)
        {
            UInt32 headerLength = (uint)input.ReadInt16();

            sof.prec = input.ReadByte();
            sof.h    = (uint)input.ReadInt16();
            sof.w    = (uint)input.ReadInt16();

            sof.cps = input.ReadByte();

            if (sof.prec > 16)
            {
                throw new Exception("LJpegDecompressor: More than 16 bits per channel is not supported.");
            }

            if (sof.cps > 4 || sof.cps < 1)
            {
                throw new Exception("LJpegDecompressor: Only from 1 to 4 components are supported.");
            }

            if (headerLength != 8 + sof.cps * 3)
            {
                throw new Exception("LJpegDecompressor: Header size mismatch.");
            }

            for (UInt32 i = 0; i < sof.cps; i++)
            {
                sof.compInfo[i].componentId = input.ReadByte();
                UInt32 subs = input.ReadByte();
                frame.compInfo[i].superV = subs & 0xf;
                frame.compInfo[i].superH = subs >> 4;
                UInt32 Tq = input.ReadByte();
                if (Tq != 0)
                {
                    throw new Exception("LJpegDecompressor: Quantized components not supported.");
                }
            }
            sof.initialized = true;
        }