public virtual void Extract(sbyte[] segmentBytes, Com.Drew.Metadata.Metadata metadata, JpegSegmentType segmentType) { if (segmentBytes == null) { throw new ArgumentNullException("segmentBytes cannot be null"); } if (metadata == null) { throw new ArgumentNullException("metadata cannot be null"); } if (segmentType == null) { throw new ArgumentNullException("segmentType cannot be null"); } try { ByteArrayReader reader = new ByteArrayReader(segmentBytes); // // Check for the header preamble // try { if (!reader.GetString(0, JpegExifSegmentPreamble.Length).Equals(JpegExifSegmentPreamble)) { // TODO what do to with this error state? System.Console.Error.Println("Invalid JPEG Exif segment preamble"); return; } } catch (IOException e) { // TODO what do to with this error state? Sharpen.Runtime.PrintStackTrace(e, System.Console.Error); return; } // // Read the TIFF-formatted Exif data // new TiffReader().ProcessTiff(reader, new ExifTiffHandler(metadata, _storeThumbnailBytes), JpegExifSegmentPreamble.Length); } catch (TiffProcessingException e) { // TODO what do to with this error state? Sharpen.Runtime.PrintStackTrace(e, System.Console.Error); } catch (IOException e) { // TODO what do to with this error state? Sharpen.Runtime.PrintStackTrace(e, System.Console.Error); } }
public virtual void ProcessChunk([NotNull] string fourCC, [NotNull] sbyte[] payload) { // System.out.println("Chunk " + fourCC + " " + payload.length + " bytes"); if (fourCC.Equals("EXIF")) { new ExifReader().Extract(new ByteArrayReader(payload), _metadata); } else { if (fourCC.Equals("ICCP")) { new IccReader().Extract(new ByteArrayReader(payload), _metadata); } else { if (fourCC.Equals("XMP ")) { new XmpReader().Extract(payload, _metadata); } else { if (fourCC.Equals("VP8X") && payload.Length == 10) { RandomAccessReader reader = new ByteArrayReader(payload); reader.SetMotorolaByteOrder(false); try { // Flags // boolean hasFragments = reader.getBit(0); bool isAnimation = reader.GetBit(1); // boolean hasXmp = reader.getBit(2); // boolean hasExif = reader.getBit(3); bool hasAlpha = reader.GetBit(4); // boolean hasIcc = reader.getBit(5); // Image size int widthMinusOne = reader.GetInt24(4); int heightMinusOne = reader.GetInt24(7); WebpDirectory directory = new WebpDirectory(); directory.SetInt(WebpDirectory.TagImageWidth, widthMinusOne + 1); directory.SetInt(WebpDirectory.TagImageHeight, heightMinusOne + 1); directory.SetBoolean(WebpDirectory.TagHasAlpha, hasAlpha); directory.SetBoolean(WebpDirectory.TagIsAnimation, isAnimation); _metadata.AddDirectory(directory); } catch (IOException e) { Sharpen.Runtime.PrintStackTrace(e, System.Console.Error); } } } } } }
public virtual Face[] GetDetectedFaces() { sbyte[] bytes = GetByteArray(TagFaceDetectionInfo); if (bytes == null) { return null; } RandomAccessReader reader = new ByteArrayReader(bytes); reader.SetMotorolaByteOrder(false); try { int faceCount = reader.GetUInt16(0); if (faceCount == 0) { return null; } Face[] faces = new Face[faceCount]; for (int i = 0; i < faceCount; i++) { int offset = 2 + i * 8; faces[i] = new Face(reader.GetUInt16(offset), reader.GetUInt16(offset + 2), reader.GetUInt16(offset + 4), reader.GetUInt16(offset + 6), null, null); } return faces; } catch (IOException) { return null; } }
public virtual Face[] GetRecognizedFaces() { sbyte[] bytes = GetByteArray(TagFaceRecognitionInfo); if (bytes == null) { return null; } RandomAccessReader reader = new ByteArrayReader(bytes); reader.SetMotorolaByteOrder(false); try { int faceCount = reader.GetUInt16(0); if (faceCount == 0) { return null; } Face[] faces = new Face[faceCount]; for (int i = 0; i < faceCount; i++) { int offset = 4 + i * 44; string name = Sharpen.Extensions.Trim(reader.GetString(offset, 20, "ASCII")); string age = Sharpen.Extensions.Trim(reader.GetString(offset + 28, 20, "ASCII")); faces[i] = new Face(reader.GetUInt16(offset + 20), reader.GetUInt16(offset + 22), reader.GetUInt16(offset + 24), reader.GetUInt16(offset + 26), name, Age.FromPanasonicString(age)); } return faces; } catch (IOException) { return null; } }
/// <summary>Version specifically for dealing with XMP found in JPEG segments.</summary> /// <remarks> /// Version specifically for dealing with XMP found in JPEG segments. This form of XMP has a peculiar preamble, which /// must be removed before parsing the XML. /// </remarks> /// <param name="segmentBytes">The byte array from which the metadata should be extracted.</param> /// <param name="metadata"> /// The /// <see cref="Com.Drew.Metadata.Metadata"/> /// object into which extracted values should be merged. /// </param> /// <param name="segmentType"> /// The /// <see cref="Com.Drew.Imaging.Jpeg.JpegSegmentType"/> /// being read. /// </param> public virtual void Extract(sbyte[] segmentBytes, Com.Drew.Metadata.Metadata metadata, JpegSegmentType segmentType) { XmpDirectory directory = metadata.GetOrCreateDirectory<XmpDirectory>(); // XMP in a JPEG file has a 29 byte preamble which is not valid XML. int preambleLength = 29; // check for the header length if (segmentBytes.Length <= preambleLength + 1) { directory.AddError(Sharpen.Extensions.StringFormat("Xmp data segment must contain at least %d bytes", preambleLength + 1)); return; } ByteArrayReader reader = new ByteArrayReader(segmentBytes); string preamble = Sharpen.Runtime.GetStringForBytes(segmentBytes, 0, preambleLength); if (!"http://ns.adobe.com/xap/1.0/\x0".Equals(preamble)) { directory.AddError("XMP data segment doesn't begin with 'http://ns.adobe.com/xap/1.0/'"); return; } sbyte[] xmlBytes = new sbyte[segmentBytes.Length - preambleLength]; System.Array.Copy(segmentBytes, 29, xmlBytes, 0, xmlBytes.Length); Extract(xmlBytes, metadata); }