📄 swfdec_bits.c
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> * 2006-2007 Benjamin Otte <otte@gnome.org> * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include <zlib.h>#include "swfdec_bits.h"#include "swfdec_debug.h"#include "swfdec_decoder.h"#include "swfdec_rect.h"/** * swfdec_bits_init: * @bits: a #SwfdecBits * @buffer: buffer to use for data or NULL * * initializes @bits for use with the data in @buffer. The buffer will not be * referenced, so you are responsible for keeping it around while @bits is used. **/void swfdec_bits_init (SwfdecBits *bits, SwfdecBuffer *buffer){ g_return_if_fail (bits != NULL); if (buffer) { bits->buffer = buffer; bits->ptr = buffer->data; bits->idx = 0; bits->end = buffer->data + buffer->length; } else { memset (bits, 0, sizeof (SwfdecBits)); }}/** * swfdec_bits_init_data: * @bits: the #SwfdecBits to initialize * @data: data to initialize with * @len: length of the data * * Initializes @bits for use with the given @data. All operations on @bits will * return copies of the data, so after use, you can free the supplied data. Using * %NULL for @data is valid if @len is 0. **/voidswfdec_bits_init_data (SwfdecBits *bits, const guint8 *data, guint len){ g_return_if_fail (bits != NULL); g_return_if_fail (data != NULL || len == 0); bits->buffer = NULL; bits->ptr = data; bits->idx = 0; bits->end = bits->ptr + len;}unsigned int swfdec_bits_left (SwfdecBits *b){ if (b->ptr == NULL) return 0; g_assert (b->end >= b->ptr); g_assert (b->end > b->ptr || b->idx == 0); return (b->end - b->ptr) * 8 - b->idx;}#define SWFDEC_BITS_CHECK(b,n) G_STMT_START { \ if (swfdec_bits_left(b) < (n)) { \ SWFDEC_ERROR ("reading past end of buffer"); \ b->ptr = b->end; \ b->idx = 0; \ return 0; \ } \}G_STMT_END#define SWFDEC_BYTES_CHECK(b,n) G_STMT_START { \ gulong __bytes; \ swfdec_bits_syncbits (b); \ __bytes = b->end - b->ptr; \ if (!(__bytes > n || \ (__bytes == n && b->idx == 0))) { \ SWFDEC_ERROR ("reading past end of buffer"); \ b->ptr = b->end; \ b->idx = 0; \ return 0; \ } \} G_STMT_ENDintswfdec_bits_getbit (SwfdecBits * b){ int r; SWFDEC_BITS_CHECK (b, 1); r = ((*b->ptr) >> (7 - b->idx)) & 1; b->idx++; if (b->idx >= 8) { b->ptr++; b->idx = 0; } return r;}unsigned intswfdec_bits_getbits (SwfdecBits * b, unsigned int n){ unsigned long r = 0; unsigned int i; SWFDEC_BITS_CHECK (b, n); while (n > 0) { i = MIN (n, 8 - b->idx); r <<= i; r |= ((*b->ptr) >> (8 - i - b->idx)) & ((1 << i) - 1); n -= i; if (i == 8) { b->ptr++; } else { b->idx += i; if (b->idx >= 8) { b->ptr++; b->idx = 0; } } } return r;}unsigned intswfdec_bits_peekbits (SwfdecBits * b, unsigned int n){ SwfdecBits tmp = *b; return swfdec_bits_getbits (&tmp, n);}intswfdec_bits_getsbits (SwfdecBits * b, unsigned int n){ unsigned long r = 0; SWFDEC_BITS_CHECK (b, n); if (n == 0) return 0; r = -swfdec_bits_getbit (b); r = (r << (n - 1)) | swfdec_bits_getbits (b, n - 1); return r;}unsigned intswfdec_bits_peek_u8 (SwfdecBits * b){ SWFDEC_BYTES_CHECK (b, 1); return *b->ptr;}unsigned intswfdec_bits_get_u8 (SwfdecBits * b){ SWFDEC_BYTES_CHECK (b, 1); return *b->ptr++;}unsigned intswfdec_bits_get_u16 (SwfdecBits * b){ unsigned int r; SWFDEC_BYTES_CHECK (b, 2); r = b->ptr[0] | (b->ptr[1] << 8); b->ptr += 2; return r;}intswfdec_bits_get_s16 (SwfdecBits * b){ short r; SWFDEC_BYTES_CHECK (b, 2); r = b->ptr[0] | (b->ptr[1] << 8); b->ptr += 2; return r;}unsigned intswfdec_bits_get_u32 (SwfdecBits * b){ unsigned int r; SWFDEC_BYTES_CHECK (b, 4); r = b->ptr[0] | (b->ptr[1] << 8) | (b->ptr[2] << 16) | (b->ptr[3] << 24); b->ptr += 4; return r;}unsigned intswfdec_bits_get_bu16 (SwfdecBits *b){ unsigned int r; SWFDEC_BYTES_CHECK (b, 2); r = (b->ptr[0] << 8) | b->ptr[1]; b->ptr += 2; return r;}unsigned intswfdec_bits_get_bu24 (SwfdecBits *b){ unsigned int r; SWFDEC_BYTES_CHECK (b, 3); r = (b->ptr[0] << 16) | (b->ptr[1] << 8) | b->ptr[2]; b->ptr += 3; return r;}unsigned int swfdec_bits_get_bu32 (SwfdecBits *b){ unsigned int r; SWFDEC_BYTES_CHECK (b, 4); r = (b->ptr[0] << 24) | (b->ptr[1] << 16) | (b->ptr[2] << 8) | b->ptr[3]; b->ptr += 4; return r;}floatswfdec_bits_get_float (SwfdecBits * b){ union { gint32 i; float f; } conv; SWFDEC_BYTES_CHECK (b, 4); conv.i = *((gint32 *) b->ptr); b->ptr += 4; conv.i = GINT32_FROM_LE (conv.i); return conv.f;}/* fixup mad byte ordering of doubles in flash files. * If little endian x86 byte order is 0 1 2 3 4 5 6 7 and PPC32 byte order is * 7 6 5 4 3 2 1 0, then Flash uses 4 5 6 7 0 1 2 3. * If your architecture has a different byte ordering for storing doubles, * this conversion function will fail. To find out your byte ordering, you can * use this command line: * python -c "import struct; print struct.unpack('8c', struct.pack('d', 7.949928895127363e-275))" */static double swfdec_bits_double_to_host (double in){ union { guint32 i[2]; double d; } conv; conv.d = in;#if G_BYTE_ORDER == G_LITTLE_ENDIAN { int tmp = conv.i[0]; conv.i[0] = conv.i[1]; conv.i[1] = tmp; }#else conv.i[0] = GUINT32_FROM_LE (conv.i[0]); conv.i[1] = GUINT32_FROM_LE (conv.i[1]);#endif return conv.d;}doubleswfdec_bits_get_double (SwfdecBits * b){ double d; SWFDEC_BYTES_CHECK (b, 8); d = *((double *) b->ptr); b->ptr += 8; d = swfdec_bits_double_to_host (d); return d;}doubleswfdec_bits_get_bdouble (SwfdecBits * b){ double d;#if G_BYTE_ORDER == G_LITTLE_ENDIAN guint64 tmp; gpointer p;#endif SWFDEC_BYTES_CHECK (b, 8);#if G_BYTE_ORDER == G_BIG_ENDIAN d = *((double *) b->ptr);#elif G_BYTE_ORDER == G_LITTLE_ENDIAN tmp = *((guint64 *) b->ptr); tmp = GUINT64_FROM_BE (tmp); p = &tmp; d = *((double *) p);#endif b->ptr += 8; return d;}voidswfdec_bits_syncbits (SwfdecBits * b){ if (b->idx) { b->ptr++; b->idx = 0; }}voidswfdec_bits_get_color_transform (SwfdecBits * bits, SwfdecColorTransform * ct){ int has_add; int has_mult; int n_bits; swfdec_bits_syncbits (bits); has_add = swfdec_bits_getbit (bits); has_mult = swfdec_bits_getbit (bits);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -