📄 swfdec_bits.c
字号:
ct->bb = 0; ct->ab = 0; } swfdec_bits_syncbits (bits);}voidswfdec_bits_get_matrix (SwfdecBits * bits, cairo_matrix_t *matrix, cairo_matrix_t *inverse){ int has_scale; int has_rotate; int n_translate_bits; has_scale = swfdec_bits_getbit (bits); if (has_scale) { int n_scale_bits = swfdec_bits_getbits (bits, 5); matrix->xx = SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits, n_scale_bits)); matrix->yy = SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits, n_scale_bits)); SWFDEC_LOG ("scalefactors: x = %d/65536, y = %d/65536", SWFDEC_DOUBLE_TO_FIXED (matrix->xx), SWFDEC_DOUBLE_TO_FIXED (matrix->yy)); } else { SWFDEC_LOG ("no scalefactors given"); matrix->xx = 1.0; matrix->yy = 1.0; } has_rotate = swfdec_bits_getbit (bits); if (has_rotate) { int n_rotate_bits = swfdec_bits_getbits (bits, 5); matrix->yx = SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits, n_rotate_bits)); matrix->xy = SWFDEC_FIXED_TO_DOUBLE (swfdec_bits_getsbits (bits, n_rotate_bits)); SWFDEC_LOG ("skew: xy = %d/65536, yx = %d/65536", SWFDEC_DOUBLE_TO_FIXED (matrix->xy), SWFDEC_DOUBLE_TO_FIXED (matrix->yx)); } else { SWFDEC_LOG ("no rotation"); matrix->xy = 0; matrix->yx = 0; } n_translate_bits = swfdec_bits_getbits (bits, 5); matrix->x0 = swfdec_bits_getsbits (bits, n_translate_bits); matrix->y0 = swfdec_bits_getsbits (bits, n_translate_bits); swfdec_matrix_ensure_invertible (matrix, inverse); swfdec_bits_syncbits (bits);}static const char *swfdec_bits_skip_string (SwfdecBits *bits){ char *s; const char *end; guint len; SWFDEC_BYTES_CHECK (bits, 1); end = memchr (bits->ptr, 0, bits->end - bits->ptr); if (end == NULL) { SWFDEC_ERROR ("could not parse string"); return NULL; } len = end - (const char *) bits->ptr; s = (char *) bits->ptr; bits->ptr += len + 1; return s;}/** * swfdec_bits_get_string_with_version: * @bits: a #SwfdecBits * @version: Flash player version * * Prior to Flash 6, strings used to be encoded as LATIN1. Since Flash 6, * strings are encoded as UTF-8. This version does the check automatically * and converts strings to UTF-8. * * Returns: a UTF-8 encoded string or %NULL on error **/char *swfdec_bits_get_string_with_version (SwfdecBits *bits, guint version){ const char *s; g_return_val_if_fail (bits != NULL, NULL); s = swfdec_bits_skip_string (bits); if (s == NULL) return NULL; if (version < 6) { char *ret = g_convert (s, -1, "UTF-8", "LATIN1", NULL , NULL, NULL); if (ret == NULL) g_warning ("Could not convert string from LATIN1 to UTF-8"); return ret; } else { if (!g_utf8_validate (s, -1, NULL)) { SWFDEC_ERROR ("parsed string is not valid utf-8"); return NULL; } return g_strdup (s); }}/* FIXME: deprecated - someone remove this */char *swfdec_bits_get_string (SwfdecBits * bits){ return swfdec_bits_get_string_with_version (bits, 6);}/** * swfdec_bits_skip_bytes: * @bits: a #SwfdecBits * @n_bytes: number of bytes to skip * * Skips up to @n_bytes bytes in @bits. If not enough bytes are available, * only the available amount is skipped and a warning is printed. * * Returns: the number of bytes actually skipped **/guintswfdec_bits_skip_bytes (SwfdecBits *bits, guint n_bytes){ g_assert (bits->idx == 0); if ((guint) (bits->end - bits->ptr) < n_bytes) { SWFDEC_WARNING ("supposed to skip %u bytes, but only %td available", n_bytes, bits->end - bits->ptr); n_bytes = bits->end - bits->ptr; } bits->ptr += n_bytes; return n_bytes;}/** * swfdec_bits_get_string_length: * @bits: a #SwfdecBits * @len: number of bytes to read * * Reads the next @len bytes into a string and validates it as UTF-8. * * Returns: a new string or %NULL on error **/char *swfdec_bits_get_string_length (SwfdecBits * bits, guint len){ char *ret; if (len == 0) return g_strdup (""); SWFDEC_BYTES_CHECK (bits, len); ret = g_strndup ((char *) bits->ptr, len); bits->ptr += len; if (!g_utf8_validate (ret, -1, NULL)) { SWFDEC_ERROR ("parsed string is not valid utf-8"); g_free (ret); ret = NULL; } return ret;}SwfdecColorswfdec_bits_get_color (SwfdecBits * bits){ guint r, g, b; r = swfdec_bits_get_u8 (bits); g = swfdec_bits_get_u8 (bits); b = swfdec_bits_get_u8 (bits); return SWFDEC_COLOR_COMBINE (r, g, b, 0xff);}SwfdecColorswfdec_bits_get_rgba (SwfdecBits * bits){ guint r, g, b, a; r = swfdec_bits_get_u8 (bits); g = swfdec_bits_get_u8 (bits); b = swfdec_bits_get_u8 (bits); a = swfdec_bits_get_u8 (bits); return SWFDEC_COLOR_COMBINE (r, g, b, a);}SwfdecGradient *swfdec_bits_get_gradient (SwfdecBits * bits){ SwfdecGradient *grad; guint i, n_gradients; n_gradients = swfdec_bits_get_u8 (bits); grad = g_malloc (sizeof (SwfdecGradient) + sizeof (SwfdecGradientEntry) * (MAX (n_gradients, 1) - 1)); for (i = 0; i < n_gradients && swfdec_bits_left (bits); i++) { grad->array[i].ratio = swfdec_bits_get_u8 (bits); grad->array[i].color = swfdec_bits_get_color (bits); } if (i < n_gradients) { SWFDEC_ERROR ("not enough data for %u gradients, could only read %u", n_gradients, i); } grad->n_gradients = i; return grad;}SwfdecGradient *swfdec_bits_get_gradient_rgba (SwfdecBits * bits){ SwfdecGradient *grad; guint i, n_gradients; n_gradients = swfdec_bits_get_u8 (bits); grad = g_malloc (sizeof (SwfdecGradient) + sizeof (SwfdecGradientEntry) * (n_gradients - 1)); for (i = 0; i < n_gradients && swfdec_bits_left (bits); i++) { grad->array[i].ratio = swfdec_bits_get_u8 (bits); grad->array[i].color = swfdec_bits_get_rgba (bits); } if (i < n_gradients) { SWFDEC_ERROR ("not enough data for %u gradients, could only read %u", n_gradients, i); } grad->n_gradients = i; return grad;}SwfdecGradient *swfdec_bits_get_morph_gradient (SwfdecBits * bits){ SwfdecGradient *grad; guint i, n_gradients; n_gradients = swfdec_bits_get_u8 (bits); n_gradients *= 2; grad = g_malloc (sizeof (SwfdecGradient) + sizeof (SwfdecGradientEntry) * (n_gradients - 1)); for (i = 0; i < n_gradients && swfdec_bits_left (bits); i++) { grad->array[i].ratio = swfdec_bits_get_u8 (bits); grad->array[i].color = swfdec_bits_get_rgba (bits); } if (i < n_gradients) { SWFDEC_ERROR ("not enough data for %u gradients, could only read %u", n_gradients, i); } grad->n_gradients = i; return grad;}voidswfdec_bits_get_rect (SwfdecBits * bits, SwfdecRect *rect){ int nbits; nbits = swfdec_bits_getbits (bits, 5); rect->x0 = swfdec_bits_getsbits (bits, nbits); rect->x1 = swfdec_bits_getsbits (bits, nbits); rect->y0 = swfdec_bits_getsbits (bits, nbits); rect->y1 = swfdec_bits_getsbits (bits, nbits); swfdec_bits_syncbits (bits);}/** * swfdec_bits_get_buffer: * @bits: #SwfdecBits * @len: length of buffer or -1 for maximum * * Gets the contents of the next @len bytes of @bits and buts them in a new * subbuffer. If @len is 0 (or @len is -1 and no more data is available), this * is considered a reading error and %NULL is returned. * * Returns: the new #SwfdecBuffer or NULL if the requested amount of data * isn't available **/SwfdecBuffer *swfdec_bits_get_buffer (SwfdecBits *bits, int len){ SwfdecBuffer *buffer; g_return_val_if_fail (len >= -1, NULL); if (len > 0) { SWFDEC_BYTES_CHECK (bits, (guint) len); } else { g_assert (bits->idx == 0); len = bits->end - bits->ptr; g_assert (len >= 0); } if (len == 0) return NULL; if (bits->buffer) { buffer = swfdec_buffer_new_subbuffer (bits->buffer, bits->ptr - bits->buffer->data, len); } else { buffer = swfdec_buffer_new_and_alloc (len); memcpy (buffer->data, bits->ptr, len); } bits->ptr += len; return buffer;}static void *swfdec_bits_zalloc (void *opaque, guint items, guint size){ return g_malloc (items * size);}static voidswfdec_bits_zfree (void *opaque, void *addr){ g_free (addr);}/** * swfdec_bits_decompress: * @bits: a #SwfdecBits * @compressed: number of bytes to decompress or -1 for the rest * @decompressed: number of bytes to expect in the decompressed result or -1 * if unknown * * Decompresses the next @compressed bytes of data in @bits using the zlib * decompression algorithm and returns the result in a buffer. If @decompressed * was set and not enough data is available, the return buffer will be filled * up with 0 bytes. * * Returns: a new #SwfdecBuffer containing the decompressed data or NULL on * failure. If @decompressed > 0, the buffer's length will be @decompressed. **/SwfdecBuffer *swfdec_bits_decompress (SwfdecBits *bits, int compressed, int decompressed){ z_stream z = { 0, }; SwfdecBuffer *buffer; int result; g_return_val_if_fail (bits != NULL, NULL); g_return_val_if_fail (compressed >= -1, NULL); g_return_val_if_fail (decompressed > 0 || decompressed == -1, NULL); /* prepare the bits structure */ if (compressed > 0) { SWFDEC_BYTES_CHECK (bits, (guint) compressed); } else { g_assert (bits->idx == 0); compressed = bits->end - bits->ptr; g_assert (compressed >= 0); } if (compressed == 0) return NULL; z.zalloc = swfdec_bits_zalloc; z.zfree = swfdec_bits_zfree; z.opaque = NULL; z.next_in = (Bytef *) bits->ptr; z.avail_in = compressed; result = inflateInit (&z); if (result != Z_OK) { SWFDEC_ERROR ("Error initialising zlib: %d %s", result, z.msg ? z.msg : ""); goto fail; } buffer = swfdec_buffer_new_and_alloc (decompressed > 0 ? decompressed : compressed * 2); z.next_out = buffer->data; z.avail_out = buffer->length; while (TRUE) { result = inflate (&z, decompressed > 0 ? Z_FINISH : 0); switch (result) { case Z_STREAM_END: goto out; case Z_OK: if (decompressed < 0) { buffer->data = g_realloc (buffer->data, buffer->length + compressed); buffer->length += compressed; z.next_out = buffer->data + z.total_out; z.avail_out = buffer->length - z.total_out; goto out; } /* else fall through */ default: SWFDEC_ERROR ("error decompressing data: inflate returned %d %s", result, z.msg ? z.msg : ""); swfdec_buffer_unref (buffer); goto fail; } }out: if (decompressed < 0) { buffer->length = z.total_out; } else { if (buffer->length < z.total_out) { SWFDEC_WARNING ("Not enough data decompressed: %lu instead of %u expected", z.total_out, buffer->length); memset (buffer->data + z.total_out, 0, buffer->length - z.total_out); } } result = inflateEnd (&z); if (result != Z_OK) { SWFDEC_ERROR ("error in inflateEnd: %d %s", result, z.msg ? z.msg : ""); } bits->ptr += compressed; return buffer;fail: bits->ptr += compressed; return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -