private NetpbmHeader <TPixelFormat> ReadPGMOrPPMHeader <TPixelFormat>(Stream stream, ValueEncoding valueEncoding, IImageFactory <TPixelFormat> imageFactory, params Component[] components) { int width; var widthBytes = SkipWhitespaceAndReadUntilNextWhitespaceByte(stream, true); var widthString = GetUsAsciiString(widthBytes); if (!TryParseIntInvariant(widthString, out width)) { throw new InvalidDataException(string.Format("failed to parse width '{0}'", widthString)); } int height; var heightBytes = SkipWhitespaceAndReadUntilNextWhitespaceByte(stream, true); var heightString = GetUsAsciiString(heightBytes); if (!TryParseIntInvariant(heightString, out height)) { throw new InvalidDataException(string.Format("failed to parse height '{0}'", heightString)); } var highestValueBytes = SkipWhitespaceAndReadUntilNextWhitespaceByte(stream, true); var highestValueString = GetUsAsciiString(highestValueBytes); TPixelFormat highestValue = imageFactory.ParseHighestComponentValue(highestValueString); // final byte of whitespace has been discarded by SkipWhitespaceAndReadUntilNextWhitespaceByte return(new NetpbmHeader <TPixelFormat>( (components.Length == 1) ? ((valueEncoding == ValueEncoding.Binary) ? ImageType.PGM : ImageType.PlainPGM) : ((valueEncoding == ValueEncoding.Binary) ? ImageType.PPM : ImageType.PlainPPM), width, height, imageFactory.GetNumberOfBytesPerPixelComponent(highestValue), components, highestValue )); //return imageFactory.MakeImage(width, height, highestValue, components, rows); }
private NetpbmHeader <TPixelFormat> ReadPAMHeader <TPixelFormat>(Stream stream, IImageFactory <TPixelFormat> imageFactory) { // ensure the next character is a newline var newline = stream.ReadByte(); if (newline == -1) { throw new EndOfStreamException(); } else if (newline != '\n') { throw new InvalidDataException("byte after magic is not a newline"); } int? width = null; int? height = null; int? depth = null; string maxValueString = null; string tupleType = ""; bool headerEnded = false; while (!headerEnded) { var lineBytes = ReadUntilAndDiscardNewline(stream, true); var lineString = GetUsAsciiString(lineBytes); if (lineString.Length == 0) { // empty line continue; } if (lineString[0] == '#') { // comment continue; } string keyword, value; SplitKeywordAndValue(lineString, out keyword, out value); int intValue; switch (keyword.ToUpperInvariant()) { case "WIDTH": if (value == null) { throw new InvalidDataException("PAM header field WIDTH is missing a value"); } if (!TryParseIntInvariant(value, out intValue)) { throw new InvalidDataException(string.Format("failed to parse width '{0}'", value)); } width = intValue; break; case "HEIGHT": if (value == null) { throw new InvalidDataException("PAM header field HEIGHT is missing a value"); } if (!TryParseIntInvariant(value, out intValue)) { throw new InvalidDataException(string.Format("failed to parse height '{0}'", value)); } height = intValue; break; case "DEPTH": if (value == null) { throw new InvalidDataException("PAM header field DEPTH is missing a value"); } if (!TryParseIntInvariant(value, out intValue)) { throw new InvalidDataException(string.Format("failed to parse depth '{0}'", value)); } depth = intValue; break; case "MAXVAL": if (value == null) { throw new InvalidDataException("PAM header field MAXVAL is missing a value"); } maxValueString = value; break; case "TUPLTYPE": if (value == null) { // never mind } else if (tupleType.Length == 0) { tupleType = value; } else { tupleType += " " + value; } break; case "ENDHDR": headerEnded = true; break; } } if (!width.HasValue) { throw new InvalidDataException("PAM header missing width"); } if (!height.HasValue) { throw new InvalidDataException("PAM header missing height"); } if (!depth.HasValue) { throw new InvalidDataException("PAM header missing depth"); } if (maxValueString == null) { throw new InvalidDataException("PAM header missing maximum value"); } // don't worry if the tuple type is missing var maxValue = imageFactory.ParseHighestComponentValue(maxValueString); var bytesPerComponent = imageFactory.GetNumberOfBytesPerPixelComponent(maxValue); var components = KnownTupleTypes.DecodeComponentString(tupleType).ToList(); if (components.Count != depth.Value) { throw new InvalidDataException("component count doesn't match depth"); } // final newline has been discarded by ReadUntilAndDiscardNewline return(new NetpbmHeader <TPixelFormat>( (bytesPerComponent > 2) ? ImageType.BigPAM : ImageType.PAM, width.Value, height.Value, bytesPerComponent, components, maxValue )); }