📄 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"#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 { \ g_assert (b->end >= b->ptr); \ g_assert (b->idx == 0); \ if ((unsigned long) (b->end - b->ptr) < n) { \ SWFDEC_ERROR ("reading past end of buffer"); \ b->ptr = b->end; \ b->idx = 0; \ return 0; \ } \} G_STMT_END/** * 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_bits: * @bits: a #SwfdecBits * @from: a #SwfdecBits to initialize from * @bytes: number of bytes to move to @bits * * Initializes @bits for use with the next @bytes bytes from @from. If not * enough bytes are available, less bytes will be available in @bits. @from * will skip the bytes now available in @bits. If you want to know if this * function moves enough bytes, you should ensure that enough data is * available using swfdec_bits_left() before calling this function. **/voidswfdec_bits_init_bits (SwfdecBits *bits, SwfdecBits *from, guint bytes){ g_return_if_fail (bits != NULL); g_return_if_fail (from != NULL); g_return_if_fail (from->idx == 0); bits->buffer = from->buffer; bits->ptr = from->ptr; if (bytes > (guint) (from->end - from->ptr)) bytes = from->end - from->ptr; bits->end = bits->ptr + bytes; bits->idx = 0; from->ptr = bits->end;}/** * 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;}guint swfdec_bits_left (const 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;}intswfdec_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;}guintswfdec_bits_getbits (SwfdecBits * b, guint n){ unsigned long r = 0; guint 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;}guintswfdec_bits_peekbits (const SwfdecBits * b, guint n){ SwfdecBits tmp = *b; return swfdec_bits_getbits (&tmp, n);}intswfdec_bits_getsbits (SwfdecBits * b, guint 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;}guintswfdec_bits_peek_u8 (const SwfdecBits * b){ g_assert (b->idx == 0); g_assert (b->ptr <= b->end); if (b->ptr == b->end) return 0; return *b->ptr;}guintswfdec_bits_get_u8 (SwfdecBits * b){ SWFDEC_BYTES_CHECK (b, 1); return *b->ptr++;}guintswfdec_bits_get_u16 (SwfdecBits * b){ guint 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;}guintswfdec_bits_get_u32 (SwfdecBits * b){ guint 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;}guintswfdec_bits_get_bu16 (SwfdecBits *b){ guint r; SWFDEC_BYTES_CHECK (b, 2); r = (b->ptr[0] << 8) | b->ptr[1]; b->ptr += 2; return r;}guintswfdec_bits_get_bu24 (SwfdecBits *b){ guint r; SWFDEC_BYTES_CHECK (b, 3); r = (b->ptr[0] << 16) | (b->ptr[1] << 8) | b->ptr[2]; b->ptr += 3; return r;}guint swfdec_bits_get_bu32 (SwfdecBits *b){ guint 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 = (b->ptr[3] << 24) | (b->ptr[2] << 16) | (b->ptr[1] << 8) | b->ptr[0]; b->ptr += 4; 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))" */doubleswfdec_bits_get_double (SwfdecBits * b){ union { guint32 i[2]; double d; } conv; SWFDEC_BYTES_CHECK (b, 8);#if G_BYTE_ORDER == G_LITTLE_ENDIAN conv.i[1] = (b->ptr[3] << 24) | (b->ptr[2] << 16) | (b->ptr[1] << 8) | b->ptr[0]; conv.i[0] = (b->ptr[7] << 24) | (b->ptr[6] << 16) | (b->ptr[5] << 8) | b->ptr[4];#else conv.i[0] = (b->ptr[3] << 24) | (b->ptr[2] << 16) | (b->ptr[1] << 8) | b->ptr[0]; conv.i[1] = (b->ptr[7] << 24) | (b->ptr[6] << 16) | (b->ptr[5] << 8) | b->ptr[4];#if 0 conv.i[0] = (b->ptr[0] << 24) | (b->ptr[1] << 16) | (b->ptr[2] << 8) | b->ptr[3]; conv.i[1] = (b->ptr[4] << 24) | (b->ptr[5] << 16) | (b->ptr[6] << 8) | b->ptr[7];#endif#endif b->ptr += 8; return conv.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; has_add = swfdec_bits_getbit (bits); has_mult = swfdec_bits_getbit (bits); n_bits = swfdec_bits_getbits (bits, 4); if (has_mult) { ct->ra = swfdec_bits_getsbits (bits, n_bits); ct->ga = swfdec_bits_getsbits (bits, n_bits); ct->ba = swfdec_bits_getsbits (bits, n_bits); ct->aa = swfdec_bits_getsbits (bits, n_bits); } else { ct->ra = 256; ct->ga = 256; ct->ba = 256; ct->aa = 256; } if (has_add) { ct->rb = swfdec_bits_getsbits (bits, n_bits); ct->gb = swfdec_bits_getsbits (bits, n_bits); ct->bb = swfdec_bits_getsbits (bits, n_bits); ct->ab = swfdec_bits_getsbits (bits, n_bits); } else { ct->rb = 0; ct->gb = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -