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>(); }
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; }
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; } } }