require 'rexml/document'

#Copyright by Torben Schinke 2007
#Lizenz: Ich kein Support/Garantie etc., du mach was willst

#Version 0.01 24.9.07

class MetaXMP
  attr_accessor :country #tiff:Country
  attr_accessor :camera #tiff:Model
  attr_accessor :cam_manufactor #tiff:Make
  attr_accessor :width #tiff:ImageWidth
  attr_accessor :exposureTime #exif:ExposureTime
  attr_accessor :country #photoshop:Country
  attr_accessor :state #photoshop:State
  attr_accessor :city #photoshop:City
  attr_accessor :location #Iptc4xmpCore:Location
  attr_accessor :creator #dc:creator/rdf:Seq/rdf:li/text()
  attr_accessor :keywords #dc:subject/rdf:Bag/rdf:li/text()
  attr_accessor :description #dc:description/rdf:Alt/rdf:li/text()
  
end

class XMP
  EXIF=0xE1
  IPTC=0xED
  
  attr_reader :metaXMP
  def initialize(filename)
    @file   = File.open(filename,"rb")# achtung windows binär öffnen
    getChunks
  end
  
  def getChunks
    buffer =Array.new
    if @file.readchar==0xFF and @file.readchar==0xD8
      while not @file.eof?
        kennung =[@file.readchar,@file.readchar]
        laenge = 256 * @file.readchar +  @file.readchar
        if kennung[0]!=0xFF
          p "============="
          p "Fehler, Kennung verpasst"
          p "gelesen "+kennung[0].to_s(16)+" "+kennung[1].to_s(16)
          p "laenge "+laenge.to_s
          p "================"
          20.times do |a|
            p @file.readchar.to_s(16)
          end
          break
        end
        
        if kennung[1]==0xDA 
          #komprimierte daten erreicht, hiernach kommt nichts mehr, wenn doch pech gehabt
          p "fertig"
          break
        end
        
        #p "gelesen "+kennung[0].to_s(16)+" "+kennung[1].to_s(16)
        #p "laenge "+laenge.to_s
        buffer << [kennung,laenge,@file.read(laenge-2)]
        #@file.seek(laenge-2,IO::SEEK_CUR  )
      end
    else
      p "Fehler, kein JFIF"
    end
   
    #p "Chunks:"
    buffer.each do |i|
      xmp=i[2]
      if xmp.index('<rdf:RDF')
        doc = REXML::Document.new(xmp,:compress_whitespace => :all)
      
        m=MetaXMP.new
        
        m.country=REXML::XPath.first(doc, '//@Country').value
        m.camera=REXML::XPath.first(doc, '//@Model').value
        m.cam_manufactor=REXML::XPath.first(doc, '//@Make').value
        m.exposureTime=REXML::XPath.first(doc, '//@ExposureTime').value
        m.state=REXML::XPath.first(doc, '//@State').value
        m.city=REXML::XPath.first(doc, '//@City').value
        m.location=REXML::XPath.first(doc, '//@Location').value
        m.creator=REXML::XPath.first(doc, '//dc:creator/rdf:Seq/rdf:li/text()')
        m.description=REXML::XPath.first(doc, '//dc:description/rdf:Alt/rdf:li/text()')
     
        m.keywords = Array.new

        REXML::XPath.each(doc, '//dc:subject/rdf:Bag/rdf:li/text()') do |n|
          m.keywords << n
        end
       @metaXMP=m
       #xmp krempel gefunden
       break 
      end

    end
  end
end

#ip=XMP.new("E:/Organisation/Bilder/Hans Sommerurlaub Sommer 2007/2007/2007-07-28/Hans Sommerurlaub 2007 (56 von 276).JPG")
#p ip.metaXMP
