public PEFFile(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); } //Raw Data: ImageFileDirectory raw = ifds[0]; IFDExif exif = raw.GetEntry <IFDExif>(); mISO = exif.GetEntry <ExifEntry.ExifISOSpeedRatings>().Value; mBitDepth = raw.GetEntry <IFDBitsPerSample>().Value; ExifEntry.ExifMakerNote makernote = exif.GetEntry <ExifEntry.ExifMakerNote>(); mBayerPattern = exif.GetEntry <ExifEntry.ExifCFAPattern>().Value; mBayerWidth = exif.GetEntry <ExifEntry.ExifCFAPattern>().xCount; mBayerHeight = exif.GetEntry <ExifEntry.ExifCFAPattern>().yCount; MNHuffmanTable huffmanTable = makernote.Value.GetEntry <MNHuffmanTable>(); mWhiteLevel = makernote.Value.GetEntry <MNWhiteLevel>(); mWhitePoint = makernote.Value.GetEntry <MNWhitePoint>(); mBlackPoint = makernote.Value.GetEntry <MNBlackPoint>(); mScaling = makernote.Value.GetEntry <MNDataScaling>(); mWidth = (int)raw.GetEntry <IFDImageWidth>().Value; mHeight = (int)raw.GetEntry <IFDImageLength>().Value; uint offset = raw.GetEntry <IFDStripOffsets>().Value[0]; Seek(offset, SeekOrigin.Begin); mRawImage = new ushort[mHeight, mWidth]; int[,] vpred = new int[2, 2]; int[] hpred = new int[2]; unsafe { fixed(ushort *huff = huffmanTable.Value) { getbithuff(-1, null); for (int row = 0; row < mHeight; row++) { for (int col = 0; col < mWidth; col++) { int diff = ljpeg_diff(huff); if (col < 2) { hpred[col] = vpred[row & 1, col] += diff; } else { hpred[col & 1] += diff; } mRawImage[row, col] = (ushort)hpred[col & 1]; } } } } }
private ImageFileDirectory SetMembers() { //Raw Data: ImageFileDirectory raw = mIfds[0]; IFDExif exif = raw.GetEntry <IFDExif>(); mISO = exif.GetEntry <ExifISOSpeedRatings>().Value; mExposureTime = exif.GetEntry <ExifExposureTime>().Value; mRecordingDate = exif.GetEntry <ExifDateTimeDigitized>().Value; mBitDepth = raw.GetEntry <IFDBitsPerSample>().Value[0]; ExifMakerNote makernote = exif.GetEntry <ExifMakerNote>(); //needed to decompress image data: mHhuffmanTable = makernote.Value.GetEntry <MNHuffmanTable>(); ExifCFAPattern.BayerColor[] bayer = exif.GetEntry <ExifCFAPattern>().Value; mBayerPattern = new BayerColor[bayer.Length]; for (int i = 0; i < bayer.Length; i++) { mBayerPattern[i] = (BayerColor)(int)bayer[i]; } MNWhiteLevel whiteLevel = makernote.Value.GetEntry <MNWhiteLevel>(); MNWhitePoint whitePoint = makernote.Value.GetEntry <MNWhitePoint>(); MNBlackPoint blackPoint = makernote.Value.GetEntry <MNBlackPoint>(); MNDataScaling scaling = makernote.Value.GetEntry <MNDataScaling>(); float whiteLevelAll = (float)Math.Pow(2, mBitDepth); if (whiteLevel != null) { whiteLevelAll = whiteLevel.Value; } mBlackLevel = new float[3]; if (blackPoint != null) { //only one value for all colors if (blackPoint.Value.Length == 1) { mBlackLevel[0] = (float)blackPoint.Value[0]; mBlackLevel[1] = (float)blackPoint.Value[0]; mBlackLevel[2] = (float)blackPoint.Value[0]; } //values per color channel if (blackPoint.Value.Length == 3) { mBlackLevel[0] = (float)blackPoint.Value[0]; mBlackLevel[1] = (float)blackPoint.Value[1]; mBlackLevel[2] = (float)blackPoint.Value[2]; } //values per color bayer pattern if (blackPoint.Value.Length == 4) { //red int indexR = -1; for (int i = 0; i < mBayerPattern.Length; i++) { if (mBayerPattern[i] == BayerColor.Red) { indexR = i; break; } } mBlackLevel[0] = (float)blackPoint.Value[indexR]; //blue int indexB = -1; for (int i = 0; i < mBayerPattern.Length; i++) { if (mBayerPattern[i] == BayerColor.Blue) { indexB = i; break; } } mBlackLevel[2] = (float)blackPoint.Value[indexB]; //green, the two remaining indices int indexG1 = -1, indexG2 = -1; for (int i = 0; i < mBayerPattern.Length; i++) { if (mBayerPattern[i] == BayerColor.Green && indexG1 == -1) { indexG1 = i; } if (mBayerPattern[i] == BayerColor.Green && indexG1 != -1) { indexG2 = i; } } float g1 = (float)blackPoint.Value[indexG1]; float g2 = (float)blackPoint.Value[indexG2]; mBlackLevel[1] = Math.Max(g1, g2); //well, one could distinguish the two greens, but what for? } } mWhiteLevel = new float[] { whiteLevelAll, whiteLevelAll, whiteLevelAll }; mWhiteLevel[0] -= mBlackLevel[0]; mWhiteLevel[1] -= mBlackLevel[1]; mWhiteLevel[2] -= mBlackLevel[2]; float scale = scaling.Value; mWhiteBalance = new float[] { whitePoint.Value[0] / scale, whitePoint.Value[1] / scale, whitePoint.Value[3] / scale }; if (makernote.Value.GetEntry <MNLevelInfo>() != null) { mRollAngle = makernote.Value.GetEntry <MNLevelInfo>().Value.RollAngle; mRollAnglePresent = true; } mWidth = (int)raw.GetEntry <IFDImageWidth>().Value; mHeight = (int)raw.GetEntry <IFDImageLength>().Value; //look for orientation tag. if (raw.GetEntry <IFDOrientation>() != null) { mOrientation = new DNGOrientation(raw.GetEntry <IFDOrientation>().Value); } else { //no tag found, use default mOrientation = new DNGOrientation(DNGOrientation.Orientation.Normal); } //we always crop at least two pixels because of our algos... mCropLeft = 2; mCropTop = 2; mCroppedWidth = mWidth - 4; mCroppedHeight = mHeight - 4; mMake = raw.GetEntry <IFDMake>().Value; mUniqueModelName = raw.GetEntry <IFDModel>().Value; //missing data, like noise model, crop area, etc..., must be loaded afterwards! double[] colorMatrix = new double[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; mColorSpec = new DNGColorSpec(colorMatrix, colorMatrix, IFDDNGCalibrationIlluminant.Illuminant.D50, IFDDNGCalibrationIlluminant.Illuminant.D50, mWhiteBalance); return(raw); }
public PEFFile(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); } //Raw Data: ImageFileDirectory raw = ifds[0]; IFDExif exif = raw.GetEntry <IFDExif>(); mISO = exif.GetEntry <ExifEntry.ExifISOSpeedRatings>().Value; mBitDepth = raw.GetEntry <IFDBitsPerSample>().Value; ExifEntry.ExifMakerNote makernote = exif.GetEntry <ExifEntry.ExifMakerNote>(); mBayerPattern = exif.GetEntry <ExifEntry.ExifCFAPattern>().Value; mBayerWidth = exif.GetEntry <ExifEntry.ExifCFAPattern>().xCount; mBayerHeight = exif.GetEntry <ExifEntry.ExifCFAPattern>().yCount; MNHuffmanTable huffmanTable = makernote.Value.GetEntry <MNHuffmanTable>(); mWhiteLevel = makernote.Value.GetEntry <MNWhiteLevel>(); mWhitePoint = makernote.Value.GetEntry <MNWhitePoint>(); mBlackPoint = makernote.Value.GetEntry <MNBlackPoint>(); mScaling = makernote.Value.GetEntry <MNDataScaling>(); mWidth = (int)raw.GetEntry <IFDImageWidth>().Value; mHeight = (int)raw.GetEntry <IFDImageLength>().Value; uint offset = raw.GetEntry <IFDStripOffsets>().Value[0]; }