# ATOM(BOX) FIELD CHANGE # Usage: ruby atomChange.rb infile outfile # Ver: 1.0.2 # Hist: # 2007/11/13・・・構築 # 2007/11/14・・・高速化 # 2007/11/15・・・fsearchのデバッグ # 2009/09/26・・・一行入魂様よりご指摘いただいたFILE SEARCH関数の修正 # http://aoyagikouhei.blog8.fc2.com/blog-entry-64.html # #------------------------------------------------------------------------------------------- # VARS IN_FILE = ARGV[0] OUT_FILE = ARGV[1] UUID = "%A8%8C%11%D4%81%97%00%90%27%08%77%03" item0= "ftypkddi%00%00%01%00kddi3g2a" item1= "uuidcpgd" + UUID + "%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00" item2= "uuidenci" + UUID + "%00%00%00%00KDDI-SA%00W21SA%00%00%00SAMP4v2%00SAMUXv2%00" item3= "uuidmvml" + UUID + "%00%00%00%00%FF%FF%E0%00" # <- TIMESTAMP ADD AFTER #------------------------------------------------------------------------------------------- # FUNCTION # CODE 2 ASCII def code2ascii(str) if /%{1}/ =~ str conv_str = "" codes = str.split('%') codes.each{|code| if /^([0-9A-F]){2}$/ =~ code code = [code].pack("H*") elsif /^([0-9A-F]){2}.+/ =~ code code_body = [code.slice(0,2)].pack("H*") str_body = code.slice(2,code.length - 2) code = code_body + str_body end conv_str += code } return conv_str else return str end end # GET DATA VALUE def getDWORD(vword) vword = vword.unpack("H*") data_value = vword.to_s.hex return data_value.to_i end # FILE SEARCH def fsearch(file,word) pos = [] word.length.times {|start_pos| begin i_stream = open(file, "rb") rescue => ex print ex.message, "\n" exit end readed = 0 if start_pos > 0 i_stream.read(start_pos) readed = start_pos end while data = i_stream.read(1024) data = data.to_s index = data.index(word) while nil != index pos << readed + index index = data.index(word, index + 1) end readed += data.length end i_stream.close } if pos.length > 0 pos = pos.uniq pos = pos.sort{|a,b| a<=>b} return pos else return false end end #------------------------------------------------------------------------------------------- # MAIN # CHECK FILE NAME if IN_FILE == OUT_FILE print "Can't replace file" exit end # TIMESTAMP begin t = File::mtime(IN_FILE) creationTime = t.to_i + 0x7C25B080 rescue => ex print ex.message, "\n" exit end ts_s = "" ts_s += "%" + format("%02x",(creationTime / 0x1000000) & 0xFF).upcase ts_s += "%" + format("%02x",(creationTime / 0x10000) & 0xFF).upcase ts_s += "%" + format("%02x",(creationTime / 0x100) & 0xFF).upcase ts_s += "%" + format("%02x",(creationTime) & 0xFF).upcase # item3 ADD TIMESTAMP item3 += ts_s # CREATE ftyp + uuid item0_cnv = code2ascii(item0) item1_cnv = code2ascii(item1) item2_cnv = code2ascii(item2) item3_cnv = code2ascii(item3) fu_box = "" fu_box += [format("%08x",item0_cnv.length + 4)].pack("H*") fu_box += item0_cnv fu_box += [format("%08x",item1_cnv.length + 4)].pack("H*") fu_box += item1_cnv fu_box += [format("%08x",item2_cnv.length + 4)].pack("H*") fu_box += item2_cnv fu_box += [format("%08x",item3_cnv.length + 4)].pack("H*") fu_box += item3_cnv # OUTPUT FILE CREATE begin o_stream = open(OUT_FILE, "wb") o_stream.print "" o_stream.close rescue => ex print ex.message, "\n" exit end # stco POSITION stco_pos = fsearch(IN_FILE,"stco") # ATOM CHANGE begin # INPUT & OUTPUT FILE OPEN i_stream = open(IN_FILE, "rb") o_stream = open(OUT_FILE, "ab") # READED BITE readed = 0 # WRITED BITE writed = 0 # ftyp & uuid WRITE o_stream.print fu_box writed = fu_box.length ftyp_length = getDWORD(i_stream.read(4)) i_stream.read(ftyp_length - 4) readed = ftyp_length diff = writed - readed # stco WRITE stco_pos.each {|spos| # WRITE BEFORE DATA before_data_length = spos - 4 - readed readed += before_data_length writed += before_data_length while before_data_length > 0 if(before_data_length > 1024) read_length = 1024 before_data_length -= 1024 else read_length = before_data_length before_data_length = 0 end o_stream.print i_stream.read(read_length) end # stco DATA LENGTH stco_length = i_stream.read(4) readed += 4 o_stream.print stco_length writed += 4 stco_length = getDWORD(stco_length) - 16 # "16" is STATIC AREA LENGTH # WRITE stco STATIC AREA stco_static_area = i_stream.read(12) readed += 12 o_stream.print stco_static_area writed += 12 # UPDATE stco while stco_length > 0 dpos = i_stream.read(4) readed += 4 stco_length -= 4 o_stream.print [format("%08x",getDWORD(dpos) + diff)].pack("H*") writed += 4 end } # LEAST DATA WRITE while data = i_stream.read(1024) o_stream.print data readed += data.length writed += data.length end # STREAM CLOSE o_stream.close i_stream.close rescue => ex print ex.message, "\n" exit end