#include "SWFReader.h" #include "SWFTag.h" #include "SWFAction.h" #include namespace SWF { Reader::Reader( const unsigned char *d, size_t l ) { data = d; length = l; pos = 0; buf = bits = 0; err = 0; } bool Reader::getData( void *dst, size_t len ) { if( pos+len > length ) { err = SWFR_EOF; pos = length+1; return false; } else { memcpy( dst, &data[pos], len ); pos += len; return true; } } uint8_t Reader::getByte() { if( pos+1 > length ) { err = SWFR_EOF; pos = length+1; return 0; } return data[pos++]; } uint16_t Reader::getWord() { if( pos+2 > length ) { err = SWFR_EOF; pos = length+1; return 0; } // FIXME x86-centric? int r = data[pos++]; r += data[pos++]<<8; return r; } uint32_t Reader::getInt() { if( pos+4 > length ) { err = SWFR_EOF; pos = length+1; return 0; } int r; // FIXME x86-centric? r = data[pos++]; r += data[pos++]<<8; r += data[pos++]<<16; r += data[pos++]<<24; return r; } uint64_t Reader::getInt64() { if( pos+8 > length ) { err = SWFR_EOF; pos = length+1; return 0; } uint64_t val; val = (uint64_t)getInt() << 32; val |= (uint64_t)getInt(); return( val ); } uint32_t Reader::getU30() { uint32_t r = 0; unsigned char c; for( int i = 0; i < 5; i++ ) { c = data[pos++]; r |= (c & 0x7F) << (7 * i); if( !(c & 0x80) ) { return r; } if( pos > length ) { err = SWFR_EOF; pos = length+1; return 0; } } return r; } int Reader::getS24() { if( pos+3 > length ) { err = SWFR_EOF; pos = length+1; return 0; } int r = data[pos++]; r += data[pos++]<<8; r += ((signed char)data[pos++])<<16; return r; } float Reader::getFloat() { /* if( pos+4 > length ) { err = SWFR_EOF; pos = length+1; return 0; } // FIXME x86-centric? int r = data[pos++]; r += data[pos++]<<8; r += data[pos++]<<16; r += data[pos++]<<24; return *((float*)&r); */ union { float f; uint32_t ul; } u; u.ul = getInt(); return u.f; } double Reader::getDouble() { /* if( pos+8 > length ) { err = SWFR_EOF; pos = length+1; return 0; } // FIXME x86-centric? char value[8]; value[4] = data[pos++]; value[5] = data[pos++]; value[6] = data[pos++]; value[7] = data[pos++]; value[0] = data[pos++]; value[1] = data[pos++]; value[2] = data[pos++]; value[3] = data[pos++]; return *(double*)value; */ union { double d; uint64_t ull; } u; u.ull = getInt64(); return u.d; } double Reader::getDouble2() { if( pos+8 > length ) { err = SWFR_EOF; pos = length+1; return 0; } union { double d; char c[8]; } u; // FIXME x86-centric? for( int i = 0; i < 8; i++ ) { u.c[i] = data[pos++]; } return u.d; } float Reader::getHalf() { uint16_t r = getWord(); int sign = (r & 0x8000) >> 15; int exp = (r & 0x7C00) >> 10; int man = (r & 0x3FF); if(exp == 0) { if(man != 0) { while(!(man & 0x400)) { man <<= 1; exp -= 1; } exp += 1 - 15 + 127; man &= 0x3FF; } } else if(exp == 0x1F) { exp = 0xFF; } else { exp += -15 + 127; } union { float f; uint32_t ul; } u; u.ul = (sign << 31) | (exp << 23) | (man << 13); return u.f; } unsigned int Reader::getEncodedU32() { unsigned int result = data[pos++]; if (!(result & 0x00000080)) return result; result = (result & 0x0000007f) | data[pos++] << 7; if (!(result & 0x00004000)) return result; result = (result & 0x00003fff) | data[pos++] << 14; if (!(result & 0x00200000)) return result; result = (result & 0x001fffff) | data[pos++] << 21; if (!(result & 0x10000000)) return result; result = (result & 0x0fffffff) | data[pos++] << 28; return result; } double Reader::getFixed( int bytesize, int exp ) { /* putFixed/getFixed are deprecated: they implicitly to byteAlign */ double r = 0; if( pos+bytesize > length ) { err = SWFR_EOF; pos = length+1; return 0; } for( int i=0; i bits ) { n -= bits; while( n > 8 ) { r <<= 8; r += getByte(); n-=8; } buf = getByte(); if( n > 0 ) { r <<= n; bits = 8-n; r += buf >> (8-n); buf &= (1<> (bits-n); bits -= n; buf &= (1<=0; b-- ) { printf( d[i] & (1<