Odczyt nagłówka SWF

0

Potrzebuję odczytać z pliku SWF informacje:

  • wersja
  • wysokość, szerokość
  • liczba ramek
  • FPS
  • sygnatura (czy sygnatura określa, czy materiał jest skompresowany?)
  • kolor tła
    oraz opcjonalnie
  • czy skompresowany
  • czy zaszyfrowany
    Jak zagooglałem, to dostałem wynik we wszystkich językach tylko nie Delphi ;-( Mógłby ktoś pomóc [???]
0

Podaj kod do Borland C++ to może da sie przerobić na delphi.

0
adus41 napisał(a)

Borland C++

Mam w ASP, PHP, Javie, C# i RoR. Mogłem sprawdzić tylko ten w PHP i wiem, że dobrze czyta. W C++ nie ma :-O Podaję w PHP, może coś uda się wykombinować:

<?php
//-----------------------------------------------------------------------------
// SWF HEADER - version 1.0
// Small utility class to determine basic data from a SWF file header
// Does not need any php-flash extension, based on raw binary data reading
// This class is maintained at http://slainte.phpclasses.org/swfheader
// This class got 2nd place on PHPCLASSES INNOVATION AWARD in May '04
// Suggestion - Set TAB size to 2 for easy reading
//----------------------------------------------------------------------------- 
//    SWFHEADER CLASS - PHP SWF header parser
//    Copyright (C) 2004  Carlos Falo Herv?s
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//----------------------------------------------------------------------------- 

class swfheader {

    var $debug ;                // Output DEBUG info
    var $fname ;                // SWF file analyzed
    var $magic ;                // Magic in a SWF file (FWS or CWS)
    var $compressed ;        // Flag to indicate a compressed file (CWS)
    var $version ;            // Flash version
    var $size ;                    // Uncompressed file size (in bytes)
    var $width ;                // Flash movie native width
    var $height ;                // Flash movie native height
    var $valid ;                // Valid SWF file
    var $fps ;                    // Flash movie native frame-rate
    var $frames ;                // Flash movie total frames

    //---------------------------------------------------------------------------     
    // swfheader($debug) :     Constructor, basically does nothing but initilize 
    //                                            debug and data fields
    //--------------------------------------------------------------------------- 
    function swfheader($debug = false) {
        $this->debug = $debug ;
        $this->init() ;
      }

    //---------------------------------------------------------------------------
    // init() : initialize the data fields to "empty" values
    //---------------------------------------------------------------------------
    function init() {
        $this->valid             = false ;
        $this->fname          = "" ;
        $this->magic            = "" ;
        $this->compressed = false ;
        $this->version         = 0 ;
        $this->width             = 0 ;
        $this->height            = 0 ;
        $this->size                = 0 ;
        $this->frames            = 0 ;
        $this->fps[]             = Array() ;
        if ($this->debug) echo "DEBUG: Data values initialized<br>" ;
      }

    //---------------------------------------------------------------------------
    // loadswf($filename) : loads $filename and stores data from it's header
    //---------------------------------------------------------------------------
    function loadswf($filename) {
        $this->fname = $filename ;
        $fp = @fopen($filename,"rb") ;
        if ($fp) {
            if ($this->debug) echo "DEBUG: Opened " . $this->fname . "<br>" ;
            // Read MAGIC FIELD
            $this->magic = fread($fp,3) ;
            if ($this->magic!="FWS" && $this->magic!="CWS") {
                if ($this->debug) echo "DEBUG: " . $this->fname . " is not a valid/supported SWF file<br>" ;
                $this->valid =  0 ;
            } else {
                // Compression
                if (substr($this->magic,0,1)=="C") $this->compressed = true ;
                else $this->compressed = false ;
                if ($this->debug) echo "DEBUG: Read MAGIC signature: " . $this->magic . "<br>" ;
                // Version
                $this->version = ord(fread($fp,1)) ;
                if ($this->debug) echo "DEBUG: Read VERSION: " . $this->version . "<br>" ;
                // Size
                $lg = 0 ;
                // 4 LSB-MSB
                for ($i=0;$i<4;$i++) {
                    $t = ord(fread($fp,1)) ;
                    if ($this->debug) echo "DEBUG: Partial SIZE read: " . ($t<<(8*$i)) . "<br>" ;
                    $lg += ($t<<(8*$i)) ;
                    }
                $this->size = $lg ;
                if ($this->debug) echo "DEBUG: Total SIZE: " . $this->size . "<br>" ;
                // RECT... we will "simulate" a stream from now on... read remaining file
                $buffer = fread($fp,$this->size) ;
                if ($this->compressed) {
                    // First decompress GZ stream
                    $buffer = gzuncompress($buffer,$this->size) ;
                    }
                $b             = ord(substr($buffer,0,1)) ;
                $buffer = substr($buffer,1) ;
                $cbyte     = $b ;
                $bits     = $b>>3 ;
                if ($this->debug) echo "DEBUG: RECT field size: " . $bits . " bits<br>" ;
                $cval     = "" ;
                // Current byte
                $cbyte &= 7 ;
                $cbyte<<= 5 ;
                // Current bit (first byte starts off already shifted)
                $cbit     = 2 ;
                // Must get all 4 values in the RECT
                for ($vals=0;$vals<4;$vals++) {
                    $bitcount = 0 ;
                    while ($bitcount<$bits) {
                        if ($cbyte&128) {
                            $cval .= "1" ;
                        } else {
                            $cval.="0" ;
                            }
                        $cbyte<<=1 ;
                        $cbyte &= 255 ;
                        $cbit-- ;
                        $bitcount++ ;
                        // We will be needing a new byte if we run out of bits
                        if ($cbit<0) {
                            $cbyte    = ord(substr($buffer,0,1)) ;
                            $buffer = substr($buffer,1) ;
                            $cbit = 7 ;
                            }
                      }
                    // O.k. full value stored... calculate
                    $c         = 1 ;
                    $val     = 0 ;
                    // Reverse string to allow for SUM(2^n*$atom)
                    if ($this->debug) echo "DEBUG: RECT binary value: " . $cval  ;
                    $tval = strrev($cval) ;
                    for ($n=0;$n<strlen($tval);$n++) {
                        $atom = substr($tval,$n,1) ;
                        if ($atom=="1") $val+=$c ;
                        // 2^n
                        $c*=2 ;
                      }
                    // TWIPS to PIXELS
                    $val/=20 ;
                    if ($this->debug) echo " (" . $val . ")<br>" ;
                    switch ($vals) {
                        case 0:
                            // tmp value
                            $this->width = $val ;
                        break ;
                        case 1:
                            $this->width = $val - $this->width ;
                        break ;
                        case 2:
                            // tmp value
                            $this->height = $val ;
                        break ;
                        case 3:
                            $this->height = $val - $this->height ;
                        break ;
                      }
                    $cval = "" ;
                  }
                // Frame rate
                $this->fps = Array() ;
                for ($i=0;$i<2;$i++) {
                    $t             = ord(substr($buffer,0,1)) ;
                    $buffer = substr($buffer,1) ;
                    $this->fps[] = $t ;
                    }
                if ($this->debug) echo "DEBUG: Frame rate: " . $this->fps[1] . "." . $this->fps[0] . "<br>" ;
                // Frames
                $this->frames = 0 ;
                for ($i=0;$i<2;$i++) {
                    $t             = ord(substr($buffer,0,1)) ;
                    $buffer = substr($buffer,1) ;
                    $this->frames += ($t<<(8*$i)) ;
                    }
                if ($this->debug) echo "DEBUG: Frames: " . $this->frames . "<br>" ;
                fclose($fp) ;
                if ($this->debug) echo "DEBUG: Finished processing " . $this->fname . "<br>" ;
                $this->valid =  1 ;
              }
        } else {
            $this->valid = 0 ;
            if ($this->debug) echo "DEBUG: Failed to open " . $this->fname . "<br>" ;
          }
        return $this->valid ;
      }

    //---------------------------------------------------------------------------     
    // show() : report to screen all the header info
    //--------------------------------------------------------------------------- 
    function show() {
      if ($this->valid) {
            // FNAME
            echo "<b>FILE: " . $this->fname . "</b><br>" ;
            // Magic
            echo "<b>MAGIC:</b> " . $this->magic ;
            if ($this->compressed) echo " (COMPRESSED)" ;
            echo "<br>" ;
            // Version
            echo "<b>VERSION:</b> " . $this->version . "<br>" ;
            // Size
            echo "<b>SIZE:</b> " . $this->size . " bytes <br>" ;
            // FRAMESIZE
            echo "<b>WIDHT:</B> " . $this->width . "<br>";
            echo "<b>HEIGHT:</B> " . $this->height . "<br>" ;
            // FPS
            echo "<b>FPS:</b> " . $this->fps[1] . "." . $this->fps[0] . " Frames/s <br>" ;
            // FRAMES
            echo "<b>FRAMES:</b> " . $this->frames . " FRAME <br>" ;
        } else {
            if (file_exists($this->fname))
                echo $this->fname . "is not a valid SWF file<br>" ;
            else
                if ($this->fname=="")
                    echo "SWFHEADER->SHOW : No file loaded<br>" ;
                else
                    echo "SWFHEDAR->SHOW : " . $this->fname . "was not found<br>" ;
          }
      }
        
    //---------------------------------------------------------------------------
    // display($trans) : just echo <OBJECT>/<EMBED> tags for the parsed file, if
    //                                     trans is set, WMODE is set to transparent. Uses alwyas
    //                                     Flash 7 player... can be tewaked to use exact versions
    //--------------------------------------------------------------------------- 
    function display($trans = false, $qlty = "high", $bgcolor = "#ffffff", $name = "") {
        
        $endl = chr(13) ;
        
        if ($this->valid) {
          if ($name=="") $name = substr($this->fname,0,strrpos($this->fname,".")) ;
            echo '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' . $this->version . ',0,0,0" width="' . $this->width . '" height="' . $this->height . '" id="' . $name . '" align="middle">' . $endl ;
            echo '<param name="allowScriptAccess" value="sameDomain" />' . $endl ;
            if ($trans) {
                echo '<param name="wmode" value="transparent" />' . $endl ;
              }
            echo '<param name="movie" value="' . $this->fname . '" />' . $endl ;
            echo '<param name="quality" value="' . $qlty . '" />' . $endl ;
            echo '<param name="bgcolor" value="' . $bgcolor .'" />' . $endl ;
            echo '<embed src="' . $this->fname . '" ';
            if ($trans) echo 'wmode="transparent" ' ;
            echo 'quality="' . $qlty . '" bgcolor="' . $bgcolor . '" width="' . $this->width . '" height="' . $this->height . '" name="' . $name . '" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />' . $endl ;
            echo '</object>' . $endl ;
        } else {
            if ($this->debug) {
              if ($this->fname=="") {
                    echo "SWFHEADER->DISPLAY : No loaded file in the object<br>" ;
                } else {
                    if (file_exists($this->fname)) {
                        echo "SWFHEADER->DISPLAY : " . $this->fname . " is not a valid SWF file<br>" ;
                    } else {
                        echo "SWFHEADER->DISPLAY : " . $this->fname . " was not found<br>" ;
                        }
                    }
                }
          }
    }
}
?>

Jak wynika z komentarze to właśnie sygnatura mówi, czy materiał jest skompresowany, czy nie, więc jedno z głowy :-)

0

Podaj źródło z Javy. :P Najprzyjaźniejsza chyba z tych wszystkich języków.. :D

0
Nex napisał(a)

Podaj źródło z Javy. :P

Proszę; tylko jak mówiłem nie wiem, czy działa. Mógłbyś sprawdzić przy okazji? ;-)

/**
 * SWFHeader is (c) 2006 Paul Brooks Andrus and is released under the MIT
 * License: http://www.opensource.org/licenses/mit-license.php
 */
package com.brooksandrus.utils.swf;

import java.io.*;
import java.util.zip.*;


/**
 * @author brooks
 * 
 */
public class SWFHeader extends SWFCompression
{

   private String       signature;

   private String       compressionType;

   private int          version;

   private long         size;

   private int          nbits;

   private int          xmax;

   private int          ymax;

   private int          width;

   private int          height;

   private int          frameRate;

   private int          frameCount;

   public static String COMPRESSED   = "compressed";

   public static String UNCOMPRESSED = "uncompressed";
   
   public SWFHeader()
   {
      super();
   }

   public SWFHeader( File file )
   {
      try
      {
         parseHeader( file );
      }
      catch ( Exception e )
      {
         e.printStackTrace();
      }
   }


   public SWFHeader( String fileName ) 
   {
      try
      {
         parseHeader( new File( fileName ) );
      }
      catch ( Exception e )
      {
         e.printStackTrace();
      }
   }

   public void parseHeader( File file ) throws Exception
   {  
      FileInputStream fis = null;
      byte[] temp = new byte[readFullSize(file)];//read the whole file in maybe--should maybe read just the header and then determine the true length by looking at the header's size property
      //byte[] temp = new byte[47];//read just the header instead of the whole file
      byte[] swf = null;

      try
      {
         fis = new FileInputStream( file );
         fis.read( temp );
         fis.close();
         
         

         if ( !isSWF( temp ) )
         {
            throw new Exception(
                  "File does not appear to be a swf - incorrect file signature" );
         }
         else
         {
            signature = "" + ( char ) temp[0] + ( char ) temp[1]
                  + ( char ) temp[2];
         }

         if ( isCompressed( temp[0] ) )
         {
            swf = uncompress( temp );
            compressionType = SWFHeader.COMPRESSED;
         }
         else
         {
            swf = temp;
            compressionType = SWFHeader.UNCOMPRESSED;
         }

      }
      catch ( IOException e )
      {
         System.err.println( e );
      }
      
      System.out.println( "swf byte array length: " + swf.length );
      
      // version is the 4th byte of a swf;
      version = swf[3];

      // bytes 5 - 8 represent the size in bytes of a swf
      size = readSize( swf );

      // Stage dimensions are stored in a rect

      nbits = ( ( swf[8] & 0xff ) >> 3 );

      PackedBitObj pbo = readPackedBits( swf, 8, 5, nbits );
      
      PackedBitObj pbo2 = readPackedBits( swf, pbo.nextByteIndex,
            pbo.nextBitIndex, nbits );

      PackedBitObj pbo3 = readPackedBits( swf, pbo2.nextByteIndex,
            pbo2.nextBitIndex, nbits );

      PackedBitObj pbo4 = readPackedBits( swf, pbo3.nextByteIndex,
            pbo3.nextBitIndex, nbits );

      xmax = pbo2.value;
      ymax = pbo4.value;

      width = convertTwipsToPixels( xmax );
      height = convertTwipsToPixels( ymax );

      int bytePointer = pbo4.nextByteIndex + 2;

      frameRate = swf[bytePointer];
      bytePointer++;
      
      
      int fc1 = swf[bytePointer] & 0xFF;
      bytePointer++;
      
      int fc2 = swf[bytePointer] & 0xFF;
      bytePointer++;
      
      frameCount = ( fc2 << 8 ) + fc1;
      /*
      System.out.println( "signature:   " + getSignature() );
      System.out.println( "version:     " + getVersion() );
      System.out.println( "compression: " + getCompressionType() );
      System.out.println( "size:        " + getSize() );
      System.out.println( "nbits:       " + getNbits() );
      System.out.println( "xmax:        " + getXmax() );
      System.out.println( "ymax:        " + getYmax() );
      System.out.println( "width:       " + getWidth() );
      System.out.println( "height:      " + getHeight() );
      System.out.println( "frameRate:   " + getFrameRate() );
      System.out.println( "frameCount:  " + getFrameCount() );
      */
      
   }

   public void read( byte[] output, byte[] input, int offset )
   {
      System.arraycopy( input, offset, output, 0, output.length - offset );
   }

   public PackedBitObj readPackedBits( byte[] bytes, int byteMarker,
         int bitMarker, int length )
   {
      int total = 0;
      int shift = 7 - bitMarker;
      int counter = 0;
      int bitIndex = bitMarker;
      int byteIndex = byteMarker;
      
      while ( counter < length )
      {
         for ( int i = bitMarker; i < 8; i++ )
         {
            int bit = ( ( bytes[byteMarker] & 0xff ) >> shift ) & 1;
            total = ( total << 1 ) + bit;
            bitIndex = i;
            shift--;
            counter++;
            
            if ( counter == length )
            {
               break;
            }
         }
         byteIndex = byteMarker;
         byteMarker++;
         bitMarker = 0;
         shift = 7;
      }
      return new PackedBitObj( bitIndex, byteIndex, total );
   }

   public int convertTwipsToPixels( int twips )
   {
      return twips / 20;
   }

   public int convertPixelsToTwips( int pixels )
   {
      return pixels * 20;
   }

   public boolean isSWF( byte[] signature )
   {
      String sig = "" + ( char ) signature[0] + ( char ) signature[1]
            + ( char ) signature[2];

      if ( sig.equals( "FWS" ) || sig.equals( "CWS" ) )
      {
         return true;
      }
      else
      {
         return false;
      }
   }

   public boolean isCompressed( int firstByte )
   {
      if ( firstByte == 67 )
      {
         return true;
      }
      else
      {
         return false;
      }
   }
   
   public boolean isCompressed()
   {
      boolean result = false;
      if ( signature.equalsIgnoreCase( "CWS" ) )
      {
         result = true;
      }
      return result;
   }

   public byte[] compress( byte[] bytes )
   {

      return new SWFCompressor().compress( bytes );
   }

   public byte[] uncompress( byte[] bytes ) throws DataFormatException
   {
      return new SWFDecompressor().uncompress( bytes );
   }

   /**
    * @param args
    */
   public static void main( String[] args )
   {
      if ( args.length != 1 )
      {
         System.err.println( "usage: swf_file" );
      }
      else
      {
         try
         {
            new SWFHeader( args[0] );
         }
         catch ( Exception e )
         {
            System.err.println( e.getMessage() );
         }
      }

   }

   /**
    * @return the frameCount
    */
   public int getFrameCount()
   {
      return frameCount;
   }

   /**
    * @return the frameRate
    */
   public int getFrameRate()
   {
      return frameRate;
   }

   /**
    * @return the nbits
    */
   public int getNbits()
   {
      return nbits;
   }

   /**
    * @return the signature
    */
   public String getSignature()
   {
      return signature;
   }

   /**
    * @return the size
    */
   public long getSize()
   {
      return size;
   }

   /**
    * @return the version
    */
   public int getVersion()
   {
      return version;
   }

   /**
    * @return the xmax
    */
   public int getXmax()
   {
      return xmax;
   }

   /**
    * @return the ymax
    */
   public int getYmax()
   {
      return ymax;
   }

   /**
    * @return the compressionType
    */
   public String getCompressionType()
   {
      return compressionType;
   }

   /**
    * @return the height
    */
   public int getHeight()
   {
      return height;
   }

   /**
    * @return the width
    */
   public int getWidth()
   {
      return width;
   }

}
0

o ile się nie mylę, adobe udostępnił opis formatu swf - ściągnij od nich specyfikację...

0
madmike napisał(a)

adobe udostępnił opis formatu swf

Nagłówek:
Field Type Comment
Signature UI8 Signature byte:
“F” indicates uncompressed
“C” indicates compressed (SWF 6 and later only)
Signature UI8 Signature byte always “W”
Signature UI8 Signature byte always “S”
Version UI8 Single byte file version (for example, 0x06 for SWF 6)
FileLength UI32 Length of entire file in bytes
FrameSize RECT Frame size in twips
FrameRate UI16 Frame delay in 8.8 fixed number of frames per second
FrameCount UI16 Total number of frames in file

Odczytałem sygnaturę, wersję i rozmiar danych, dalej jest rozmiar ramki (RECT) i tego już nie umiem odczytać (z oczywistych względów dalszej części nagłówka też nie ;-( ) [glowa]
RECT wygląda tak:

Field Type and Value Comment
Nbits UB[5] = 1011 Bits required (11)
Xmin SB[11] = 00001111111 x minimum in twips (127)
Xmax SB[11] = 00100000100 x maximum in twips (260)
Ymin SB[11] = 00000001111 y minimum in twips (15)
Ymax SB[11] = 01000000010 y maximum in twips (514)

Jak odczytać te 3 ostatnie pola nagłówka [???]

1 użytkowników online, w tym zalogowanych: 0, gości: 1