X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Frfxswf.c;h=278e504ce413322d104786ab2166e101ed795dec;hp=2b46f53e412da1cdd93462aeabfb45ec429f41e6;hb=98da96466d3a3d8b56da406f6231b8c524449021;hpb=195da3fa2edfd23e27836c18a34b513508319f59 diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 2b46f53..278e504 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -95,6 +95,7 @@ U8 swf_GetU8(TAG * t) #ifdef DEBUG_RFXSWF if ((int)t->pos>=(int)t->len) { fprintf(stderr,"GetU8() out of bounds: TagID = %i\n",t->id); + *(int*)0=0; return 0; } #endif @@ -408,32 +409,91 @@ int swf_SetU30String(TAG*tag, const char*str, int l) swf_SetBlock(tag, (void*)str, l); return len; } + float swf_GetF16(TAG * t) { - // D16 is 1-5-10 - // D32 is 1-8-23 U16 f1 = swf_GetU16(t); - if(!f1) return 0; - U32 f2 = (f1&0x8000)<<16; //sign - f2 |= ((f1&0x7c00)<<13)+(0x40000000-(0x4000<<13)); //exp - f2 |= (f1&0x03ff)<<13; //mantissa + if(!(f1&0x3ff)) return 0.0; + + // IEEE 16 is 1-5-10 + // IEEE 32 is 1-8-23 + /* gcc 4.1.2 seems to require a union here. *(float*)u doesn't work */ + union { + U32 u; + float f; + } f2; + + U16 e = (f1>>10)&0x1f; + U16 m = f1&0x3ff; + /* find highest bit in mantissa */ + int h=0; + while(!(m&0x400)) { + m<<=1; + h++; + } + m&=0x3ff; + e -= h; + e += 0x6f; + + f2.u = (f1&0x8000)<<16; //sign + f2.u |= e<<23; //exponent + f2.u |= m<<13; //mantissa return *(float*)&f2; } + void swf_SetF16(TAG * t, float f) { - U32 f1 = *(U32*)&f; - U16 f2 = (f1>>16)&0x8000; - int exp = ((f1>>23)&0xff)-0x80+0x10; - if(exp<0) { + union { + U32 u; + float f; + } v; + v.f = f; + + U16 result = (v.u>>16)&0x8000; //sign + int exp = ((v.u>>23)&0xff)-0x7f+0x10; + U16 m = (v.u>>13)&0x3ff; + //fprintf(stderr, "%f: %04x sign, %d exp, %04x mantissa\n", f, result, exp, m); + if(exp<-10) { + // underflow (clamp to 0.0) + exp = 0; + m = 0; + } else if(exp<0) { + // partial underflow- strip some bits + m = (m|0x400)>>-exp; exp = 0; - fprintf(stderr, "Exponent underflow in FLOAT16 encoding\n"); } else if(exp>=32) { exp = 31; + m = 0x3ff; fprintf(stderr, "Exponent overflow in FLOAT16 encoding\n"); + } else { + exp++; + m = (m>>1)|0x200; } - f2 |= exp<<10; - f2 |= (f1>>13)&0x3ff; - swf_SetU16(t, f2); + result |= exp<<10; + result |= m; + swf_SetU16(t, result); +} + +float F16toFloat(U16 x) +{ + TAG t; + t.data = (void*)&x; + t.readBit = 0; + t.pos = 0; + t.len = 2; + return swf_GetF16(&t); +} + +float floatToF16(float f) +{ + U16 u = 0; + TAG t; + t.data = (void*)&u; + t.len = 0; + t.memsize = 2; + t.writeBit = 0; + swf_SetF16(&t, f); + return u; } double swf_GetD64(TAG*tag) @@ -1126,8 +1186,7 @@ TAG * swf_ReadTag(reader_t*reader, TAG * prev) if (len==0x3f) { - if (reader->read(reader, &len, 4) != 4) return NULL; - len = SWAP32(len); + len = reader_readU32(reader); } if (id==ST_DEFINESPRITE) len = 2*sizeof(U16); @@ -1204,14 +1263,7 @@ int swf_WriteTag2(writer_t*writer, TAG * t) return -1; } - len = SWAP32(len); - if (writer->write(writer,&len,4)!=4) - { - #ifdef DEBUG_RFXSWF - fprintf(stderr,"WriteTag() failed: Long Header (2).\n"); - #endif - return -1; - } + writer_writeU32(writer, len); } if (t->data) @@ -1821,7 +1873,7 @@ int swf_WriteCGI(SWF * swf) sprintf(s,"Content-type: application/x-shockwave-flash\n" "Accept-Ranges: bytes\n" - "Content-Length: %lu\n" + "Content-Length: %d\n" "Expires: Thu, 13 Apr 2000 23:59:59 GMT\n" "\n",len);