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