Beispiel #1
0
        public DNGFile(string aFileName, bool HeaderOnly)
            : base(aFileName)
        {
            byte a = mFileReader.ReadByte();
            byte b = mFileReader.ReadByte();

            bool fileIsLittleEndian;

            if (a == b && b == 'I')
            {
                fileIsLittleEndian = true;
            }
            else
            if (a == b && b == 'M')
            {
                fileIsLittleEndian = false;
            }
            else
            {
                throw new FileLoadException("Could not determine file endianess. Is this a proper TIFF/PEF file?", aFileName);
            }

            mEndianSwap = fileIsLittleEndian != BitConverter.IsLittleEndian;

            ushort magicNumber = ReadUI2();

            if (magicNumber != 42)
            {
                throw new FileLoadException("This is not a valid TIFF/PEF file: Magic number is not 42.", aFileName);
            }

            uint offsetToFirstIFD = ReadUI4();

            mFile.Seek(offsetToFirstIFD, SeekOrigin.Begin);
            List <ImageFileDirectory> ifds = new List <ImageFileDirectory>();

            while (true)
            {
                ImageFileDirectory ifd = new ImageFileDirectory(this);
                ifds.Add(ifd);
                uint offsetToNext = ReadUI4();
                if (offsetToNext == 0)
                {
                    break;
                }
                Seek(offsetToNext, System.IO.SeekOrigin.Begin);
            }


            IFDSubIFDs sub = ifds[0].GetEntry <IFDSubIFDs>();

            mWidth  = (int)sub.Value[0].GetEntry <IFDImageWidth>().Value;
            mHeight = (int)sub.Value[0].GetEntry <IFDImageLength>().Value;
            IFDExif exif = ifds[0].GetEntry <IFDExif>();

            mISO      = exif.GetEntry <ExifEntry.ExifISOSpeedRatings>().Value;
            mBitDepth = sub.Value[0].GetEntry <IFDBitsPerSample>().Value;

            mBayerPattern       = sub.Value[0].GetEntry <IFDCFAPattern>().Value;
            mBayerWidth         = sub.Value[0].GetEntry <IFDCFARepeatPatternDim>().Value[0];
            mBayerHeight        = sub.Value[0].GetEntry <IFDCFARepeatPatternDim>().Value[1];
            mWhiteLevel         = sub.Value[0].GetEntry <IFDDNGWhiteLevel>();
            mBlackLevel         = sub.Value[0].GetEntry <IFDDNGBlackLevel>();
            mLinearizationTable = sub.Value[0].GetEntry <IFDDNGLinearizationTable>();
            mMinVal             = new float[3];
            mMinVal[0]          = (float)mBlackLevel.Value[0].Value;
            mMinVal[1]          = (float)mBlackLevel.Value[mBlackLevel.Value.Length > 1 ? 1 : 0].Value;
            mMinVal[2]          = (float)mBlackLevel.Value[mBlackLevel.Value.Length > 3 ? 3 : 0].Value;

            mMaxVal    = new float[3];
            mMaxVal[0] = (float)mWhiteLevel.Value[0];
            mMaxVal[1] = (float)mWhiteLevel.Value[mWhiteLevel.Value.Length > 1 ? 1 : 0];
            mMaxVal[2] = (float)mWhiteLevel.Value[mWhiteLevel.Value.Length > 3 ? 3 : 0];



            mAsShotNeutral = ifds[0].GetEntry <IFDDNGAsShotNeutral>();
        }
Beispiel #2
0
        public DNGColorSpec(uint aChannels, ImageFileDirectory ifd0, ImageFileDirectory raw)
        {
            fChannels = aChannels;
            if (GetTag <IFDDNGCalibrationIlluminant1>(ifd0, raw) != null)
            {
                fTemperature1 = ConvertIlluminantToTemperature(GetTag <IFDDNGCalibrationIlluminant1>(ifd0, raw).Value);
            }
            else
            {
                fTemperature1 = 0.0;
            }
            if (GetTag <IFDDNGCalibrationIlluminant2>(ifd0, raw) != null)
            {
                fTemperature2 = ConvertIlluminantToTemperature(GetTag <IFDDNGCalibrationIlluminant2>(ifd0, raw).Value);
            }
            else
            {
                fTemperature2 = 0.0;
            }

            fColorMatrix1 = GetTag <IFDDNGColorMatrix1>(ifd0, raw)?.Matrix;
            if (fColorMatrix1 == null)
            {
                fColorMatrix1 = DNGMatrix.Identity(fChannels); //best choice if nothing is given...
            }
            fColorMatrix2 = GetTag <IFDDNGColorMatrix2>(ifd0, raw)?.Matrix;
            if (fColorMatrix2 == null)
            {
                fColorMatrix2 = new DNGMatrix();
            }

            fForwardMatrix1 = GetTag <IFDDNGForwardMatrix1>(ifd0, raw)?.Matrix;
            if (fForwardMatrix1 == null)
            {
                fForwardMatrix1 = new DNGMatrix();
            }
            fForwardMatrix2 = GetTag <IFDDNGForwardMatrix2>(ifd0, raw)?.Matrix;
            if (fForwardMatrix2 == null)
            {
                fForwardMatrix2 = new DNGMatrix();
            }

            fReductionMatrix1 = GetTag <IFDDNGReductionMatrix1>(ifd0, raw)?.Matrix;
            if (fReductionMatrix1 == null)
            {
                fReductionMatrix1 = new DNGMatrix();
            }
            fReductionMatrix2 = GetTag <IFDDNGReductionMatrix2>(ifd0, raw)?.Matrix;
            if (fReductionMatrix2 == null)
            {
                fReductionMatrix2 = new DNGMatrix();
            }

            fCameraCalibration1 = GetTag <IFDDNGCameraCalibration1>(ifd0, raw)?.Matrix;
            fCameraCalibration2 = GetTag <IFDDNGCameraCalibration1>(ifd0, raw)?.Matrix;
            if (fCameraCalibration1 == null)
            {
                fCameraCalibration1 = DNGMatrix.Identity(fChannels);
            }
            if (fCameraCalibration2 == null)
            {
                fCameraCalibration2 = DNGMatrix.Identity(fChannels);
            }

            fAnalogBalance = GetTag <IFDDNGAnalogBalance>(ifd0, raw)?.Vector.AsDiagonal();
            if (fAnalogBalance == null)
            {
                fAnalogBalance = DNGMatrix.Identity(fChannels);
            }

            fForwardMatrix1 = NormalizeForwardMatrix(fForwardMatrix1);

            fColorMatrix1 = fAnalogBalance * fCameraCalibration1 * fColorMatrix1;

            if (fColorMatrix2.IsEmpty() ||
                fTemperature1 <= 0.0 ||
                fTemperature2 <= 0.0 ||
                fTemperature1 == fTemperature2)
            {
                fTemperature1 = 5000.0;
                fTemperature2 = 5000.0;

                fColorMatrix2       = fColorMatrix1;
                fForwardMatrix2     = fForwardMatrix1;
                fReductionMatrix2   = fReductionMatrix1;
                fCameraCalibration2 = fCameraCalibration1;
            }
            else
            {
                fForwardMatrix2 = NormalizeForwardMatrix(fForwardMatrix2);
                fColorMatrix2   = fAnalogBalance * fCameraCalibration2 * fColorMatrix2;

                // Swap values if temperatures are out of order.
                if (fTemperature1 > fTemperature2)
                {
                    double temp = fTemperature1;
                    fTemperature1 = fTemperature2;
                    fTemperature2 = temp;

                    DNGMatrix T = fColorMatrix1;
                    fColorMatrix1 = fColorMatrix2;
                    fColorMatrix2 = T;

                    T = fForwardMatrix1;
                    fForwardMatrix1 = fForwardMatrix2;
                    fForwardMatrix2 = T;

                    T = fReductionMatrix1;
                    fReductionMatrix1 = fReductionMatrix2;
                    fReductionMatrix2 = T;

                    T = fCameraCalibration1;
                    fCameraCalibration1 = fCameraCalibration2;
                    fCameraCalibration2 = T;
                }
            }

            IFDDNGAsShotNeutral neutral = GetTag <IFDDNGAsShotNeutral>(ifd0, raw);
            IFDDNGAsShotWhiteXY asShot  = GetTag <IFDDNGAsShotWhiteXY>(ifd0, raw);
            DNGxyCoord          white;

            if (asShot == null)
            {
                if (neutral == null)
                {
                    throw new ArgumentException("The DNG spec says that one of the As Shot White balance tags must be present.");
                }

                DNGVector vec = new DNGVector((uint)neutral.Value.Length);

                for (uint c = 0; c < neutral.Value.Length; c++)
                {
                    vec[c] = neutral.Value[c].Value;
                }

                double unify = 1.0 / vec.MaxEntry();
                vec = unify * vec;

                white = NeutralToXY(vec);
            }
            else
            {
                double x = asShot.Value[0].Value;
                double y = asShot.Value[1].Value;
                white = new DNGxyCoord(x, y);
            }
            WhiteXY = white;
        }
Beispiel #3
0
        public DNGFile(string aFileName)
            : base(aFileName)
        {
            byte a = mFileReader.ReadByte();
            byte b = mFileReader.ReadByte();

            bool fileIsLittleEndian;

            if (a == b && b == 'I')
            {
                fileIsLittleEndian = true;
            }
            else
            if (a == b && b == 'M')
            {
                fileIsLittleEndian = false;
            }
            else
            {
                throw new FileLoadException("Could not determine file endianess. Is this a proper TIFF/PEF file?", aFileName);
            }

            mEndianSwap = fileIsLittleEndian != BitConverter.IsLittleEndian;

            ushort magicNumber = ReadUI2();

            if (magicNumber != 42)
            {
                throw new FileLoadException("This is not a valid TIFF/PEF file: Magic number is not 42.", aFileName);
            }

            uint offsetToFirstIFD = ReadUI4();

            mFile.Seek(offsetToFirstIFD, SeekOrigin.Begin);
            List <ImageFileDirectory> ifds = new List <ImageFileDirectory>();

            while (true)
            {
                ImageFileDirectory ifd = new ImageFileDirectory(this);
                ifds.Add(ifd);
                uint offsetToNext = ReadUI4();
                if (offsetToNext == 0)
                {
                    break;
                }
                Seek(offsetToNext, System.IO.SeekOrigin.Begin);
            }

            IFDDNGVersion version = ifds[0].GetEntry <IFDDNGVersion>();

            isDNGVersionLarge = version == null;
            if (version != null)
            {
                isDNGVersionLarge = version.Value[1] > 1;
            }

            IFDSubIFDs sub = ifds[0].GetEntry <IFDSubIFDs>();

            mWidth  = (int)sub.Value[0].GetEntry <IFDImageWidth>().Value;
            mHeight = (int)sub.Value[0].GetEntry <IFDImageLength>().Value;
            IFDExif exif = ifds[0].GetEntry <IFDExif>();

            mISO      = exif.GetEntry <ExifEntry.ExifISOSpeedRatings>().Value;
            mBitDepth = sub.Value[0].GetEntry <IFDBitsPerSample>().Value;

            mBayerPattern = sub.Value[0].GetEntry <IFDCFAPattern>().Value;
            mBayerWidth   = sub.Value[0].GetEntry <IFDCFARepeatPatternDim>().Value[0];
            mBayerHeight  = sub.Value[0].GetEntry <IFDCFARepeatPatternDim>().Value[1];
            mWhiteLevel   = sub.Value[0].GetEntry <IFDDNGWhiteLevel>();
            mBlackLevel   = sub.Value[0].GetEntry <IFDDNGBlackLevel>();

            mAsShotNeutral = sub.Value[0].GetEntry <IFDDNGAsShotNeutral>();

            mLinearizationTable = sub.Value[0].GetEntry <IFDDNGLinearizationTable>();
            mMinVal             = new float[3];
            mMinVal[0]          = (float)mBlackLevel.Value[0].Value;
            mMinVal[1]          = (float)mBlackLevel.Value[mBlackLevel.Value.Length > 1 ? 1 : 0].Value;
            mMinVal[2]          = (float)mBlackLevel.Value[mBlackLevel.Value.Length > 3 ? 3 : 0].Value;

            mMaxVal    = new float[3];
            mMaxVal[0] = (float)mWhiteLevel.Value[0];
            mMaxVal[1] = (float)mWhiteLevel.Value[mWhiteLevel.Value.Length > 1 ? 1 : 0];
            mMaxVal[2] = (float)mWhiteLevel.Value[mWhiteLevel.Value.Length > 3 ? 3 : 0];

            int tileWidth  = (int)sub.Value[0].GetEntry <IFDTileWidth>().Value;
            int tileHeight = (int)sub.Value[0].GetEntry <IFDTileLength>().Value;

            uint[] offsets    = sub.Value[0].GetEntry <IFDTileOffsets>().Value;
            uint[] byteCounts = sub.Value[0].GetEntry <IFDTileByteCounts>().Value;

            mRawImage = new ushort[mHeight, mWidth];

            int row = 0;
            int col = 0;

            for (int tile = 0; tile < offsets.Length; tile++)
            {
                byte[] data;
                Seek(offsets[tile], SeekOrigin.Begin);
                data = mFileReader.ReadBytes((int)byteCounts[tile]);
                MemoryStream ms = new MemoryStream(data);
                ms.Seek(0, SeekOrigin.Begin);
                jhead jh = new jhead();
                int   ret = ljpeg_start(jh, 0, ms);
                int   jrow, jcol;
                if (ret > 0 && jh != null)
                {
                    int jwide = jh.wide;
                    jwide *= jh.clrs;


                    unsafe
                    {
                        if (jh.algo == 0xc3) //lossless JPEG
                        {
                            for (jrow = 0; jrow < jh.high; jrow++)
                            {
                                fixed(ushort *ptr = jh.row)
                                {
                                    jh.rowPtr = ptr;
                                    ushort *rp = ljpeg_row(jrow, jh, ms);

                                    for (jcol = 0; jcol < jwide; jcol++)
                                    {
                                        if (jcol + col < mWidth && jrow + row < mHeight)
                                        {
                                            if (mLinearizationTable != null)
                                            {
                                                mRawImage[row + jrow, col + jcol] = mLinearizationTable.Value[rp[jcol] < mLinearizationTable.Value.Length ? rp[jcol] : mLinearizationTable.Value.Length - 1];
                                            }
                                            else
                                            {
                                                mRawImage[row + jrow, col + jcol] = rp[jcol];
                                            }
                                        }
                                    }
                                    jh.rowPtr = null;
                                }
                            }
                        }
                    }
                }
                col += tileWidth;
                if (col > mWidth)
                {
                    col  = 0;
                    row += tileHeight;
                }
            }
        }