static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) { int mode; int i; int8_t dc[6]; mode = bytestream2_get_byte(&s->gb); if (mode > 12) { GetBitContext gb; init_get_bits8(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode)); for (i = 0; i < 6; i++) tgq_decode_block(s, s->block[i], &gb); tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(&s->gb, mode); } else { if (mode == 3) { memset(dc, bytestream2_get_byte(&s->gb), 4); dc[4] = bytestream2_get_byte(&s->gb); dc[5] = bytestream2_get_byte(&s->gb); } else if (mode == 6) { bytestream2_get_buffer(&s->gb, dc, 6); } else if (mode == 12) { for (i = 0; i < 6; i++) { dc[i] = bytestream2_get_byte(&s->gb); bytestream2_skip(&s->gb, 1); } } else { av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode); return -1; } tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc); } return 0; }
static int decompress_chunks_thread(AVCodecContext *avctx, void *arg, int chunk_nb, int thread_nb) { HapContext *ctx = avctx->priv_data; HapChunk *chunk = &ctx->chunks[chunk_nb]; GetByteContext gbc; uint8_t *dst = ctx->tex_buf + chunk->uncompressed_offset; bytestream2_init(&gbc, ctx->gbc.buffer + chunk->compressed_offset, chunk->compressed_size); if (chunk->compressor == HAP_COMP_SNAPPY) { int ret; int64_t uncompressed_size = ctx->tex_size; /* Uncompress the frame */ ret = ff_snappy_uncompress(&gbc, dst, &uncompressed_size); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Snappy uncompress error\n"); return ret; } } else if (chunk->compressor == HAP_COMP_NONE) { bytestream2_get_buffer(&gbc, dst, chunk->compressed_size); } return 0; }
static int dxv_decompress_raw(AVCodecContext *avctx) { DXVContext *ctx = avctx->priv_data; GetByteContext *gbc = &ctx->gbc; bytestream2_get_buffer(gbc, ctx->tex_data, ctx->tex_size); return 0; }
static int gif_read_header1(GifState *s) { uint8_t sig[6]; int v, n; int has_global_palette; if (bytestream2_get_bytes_left(&s->gb) < 13) return AVERROR_INVALIDDATA; /* read gif signature */ bytestream2_get_buffer(&s->gb, sig, 6); if (memcmp(sig, gif87a_sig, 6) != 0 && memcmp(sig, gif89a_sig, 6) != 0) return AVERROR_INVALIDDATA; /* read screen header */ s->transparent_color_index = -1; s->screen_width = bytestream2_get_le16(&s->gb); s->screen_height = bytestream2_get_le16(&s->gb); if( (unsigned)s->screen_width > 32767 || (unsigned)s->screen_height > 32767) { av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); return AVERROR_INVALIDDATA; } v = bytestream2_get_byte(&s->gb); s->color_resolution = ((v & 0x70) >> 4) + 1; has_global_palette = (v & 0x80); s->bits_per_pixel = (v & 0x07) + 1; s->background_color_index = bytestream2_get_byte(&s->gb); bytestream2_get_byte(&s->gb); /* ignored */ av_dlog(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", s->screen_width, s->screen_height, s->bits_per_pixel, has_global_palette); if (has_global_palette) { n = 1 << s->bits_per_pixel; if (bytestream2_get_bytes_left(&s->gb) < n * 3) return AVERROR_INVALIDDATA; bytestream2_get_buffer(&s->gb, s->global_palette, n * 3); } return 0; }
int ff_amf_get_string(GetByteContext *bc, uint8_t *str, int strsize, int *length) { int stringlen = 0; int readsize; stringlen = bytestream2_get_be16(bc); if (stringlen + 1 > strsize) return AVERROR(EINVAL); readsize = bytestream2_get_buffer(bc, str, stringlen); if (readsize != stringlen) { av_log(NULL, AV_LOG_WARNING, "Unable to read as many bytes as AMF string signaled\n"); } str[readsize] = '\0'; *length = FFMIN(stringlen, readsize); return 0; }
static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst, unsigned int bytes_per_scanline, int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { while (i<bytes_per_scanline) { run = 1; value = bytestream2_get_byte(gb); if (value >= 0xc0) { run = value & 0x3f; value = bytestream2_get_byte(gb); } while (i<bytes_per_scanline && run--) dst[i++] = value; } } else { bytestream2_get_buffer(gb, dst, bytes_per_scanline); } }
static int dds_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { DDSContext *ctx = avctx->priv_data; GetByteContext *gbc = &ctx->gbc; AVFrame *frame = data; int mipmap; int ret; ff_texturedsp_init(&ctx->texdsp); bytestream2_init(gbc, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(gbc) < 128) { av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", bytestream2_get_bytes_left(gbc)); return AVERROR_INVALIDDATA; } if (bytestream2_get_le32(gbc) != MKTAG('D', 'D', 'S', ' ') || bytestream2_get_le32(gbc) != 124) { // header size av_log(avctx, AV_LOG_ERROR, "Invalid DDS header.\n"); return AVERROR_INVALIDDATA; } bytestream2_skip(gbc, 4); // flags avctx->height = bytestream2_get_le32(gbc); avctx->width = bytestream2_get_le32(gbc); ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n", avctx->width, avctx->height); return ret; } /* Since codec is based on 4x4 blocks, size is aligned to 4. */ avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W); avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H); bytestream2_skip(gbc, 4); // pitch bytestream2_skip(gbc, 4); // depth mipmap = bytestream2_get_le32(gbc); if (mipmap != 0) av_log(avctx, AV_LOG_VERBOSE, "Found %d mipmaps (ignored).\n", mipmap); /* Extract pixel format information, considering additional elements * in reserved1 and reserved2. */ ret = parse_pixel_format(avctx); if (ret < 0) return ret; ret = ff_get_buffer(avctx, frame, 0); if (ret < 0) return ret; if (ctx->compressed) { int size = (avctx->coded_height / TEXTURE_BLOCK_H) * (avctx->coded_width / TEXTURE_BLOCK_W) * ctx->tex_ratio; ctx->slice_count = av_clip(avctx->thread_count, 1, avctx->coded_height / TEXTURE_BLOCK_H); if (bytestream2_get_bytes_left(gbc) < size) { av_log(avctx, AV_LOG_ERROR, "Compressed Buffer is too small (%d < %d).\n", bytestream2_get_bytes_left(gbc), size); return AVERROR_INVALIDDATA; } /* Use the decompress function on the texture, one block per thread. */ ctx->tex_data = gbc->buffer; avctx->execute2(avctx, decompress_texture_thread, frame, NULL, ctx->slice_count); } else { int linesize = av_image_get_linesize(avctx->pix_fmt, frame->width, 0); if (ctx->paletted) { int i; /* Use the first 1024 bytes as palette, then copy the rest. */ bytestream2_get_buffer(gbc, frame->data[1], 256 * 4); for (i = 0; i < 256; i++) AV_WN32(frame->data[1] + i*4, (frame->data[1][2+i*4]<<0)+ (frame->data[1][1+i*4]<<8)+ (frame->data[1][0+i*4]<<16)+ (frame->data[1][3+i*4]<<24) ); frame->palette_has_changed = 1; } if (bytestream2_get_bytes_left(gbc) < frame->height * linesize) { av_log(avctx, AV_LOG_ERROR, "Buffer is too small (%d < %d).\n", bytestream2_get_bytes_left(gbc), frame->height * linesize); return AVERROR_INVALIDDATA; } av_image_copy_plane(frame->data[0], frame->linesize[0], gbc->buffer, linesize, linesize, frame->height); } /* Run any post processing here if needed. */ if (avctx->pix_fmt == AV_PIX_FMT_BGRA || avctx->pix_fmt == AV_PIX_FMT_RGBA || avctx->pix_fmt == AV_PIX_FMT_RGB0 || avctx->pix_fmt == AV_PIX_FMT_BGR0 || avctx->pix_fmt == AV_PIX_FMT_YA8) run_postproc(avctx, frame); /* Frame is ready to be output. */ frame->pict_type = AV_PICTURE_TYPE_I; frame->key_frame = 1; *got_frame = 1; return avpkt->size; }
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size) { FlicDecodeContext *s = avctx->priv_data; GetByteContext g2; int stream_ptr_after_color_chunk; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; unsigned char palette_idx2; unsigned int frame_size; int num_chunks; unsigned int chunk_size; int chunk_type; int i, j, ret; int color_packets; int color_changes; int color_shift; unsigned char r, g, b; int lines; int compressed_lines; int starting_line; signed short line_packets; int y_ptr; int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; unsigned int pixel_limit; bytestream2_init(&g2, buf, buf_size); if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } pixels = s->frame->data[0]; pixel_limit = s->avctx->height * s->frame->linesize[0]; frame_size = bytestream2_get_le32(&g2); bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ frame_size -= 16; /* iterate through the chunks */ while ((frame_size > 0) && (num_chunks > 0)) { chunk_size = bytestream2_get_le32(&g2); chunk_type = bytestream2_get_le16(&g2); switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6; /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during * initialization) */ if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) color_shift = 0; else color_shift = 2; /* set up the palette */ color_packets = bytestream2_get_le16(&g2); palette_ptr = 0; for (i = 0; i < color_packets; i++) { /* first byte is how many colors to skip */ palette_ptr += bytestream2_get_byte(&g2); /* next byte indicates how many entries to change */ color_changes = bytestream2_get_byte(&g2); /* if there are 0 color changes, there are actually 256 */ if (color_changes == 0) color_changes = 256; for (j = 0; j < color_changes; j++) { unsigned int entry; /* wrap around, for good measure */ if ((unsigned)palette_ptr >= 256) palette_ptr = 0; r = bytestream2_get_byte(&g2) << color_shift; g = bytestream2_get_byte(&g2) << color_shift; b = bytestream2_get_byte(&g2) << color_shift; entry = (r << 16) | (g << 8) | b; if (s->palette[palette_ptr] != entry) s->new_palette = 1; s->palette[palette_ptr++] = entry; } } /* color chunks sometimes have weird 16-bit alignment issues; * therefore, take the hardline approach and skip * to the value calculated w.r.t. the size specified by the color * chunk header */ if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0) bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2)); break; case FLI_DELTA: y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { line_packets = bytestream2_get_le16(&g2); if ((line_packets & 0xC000) == 0xC000) { // line skip opcode line_packets = -line_packets; y_ptr += line_packets * s->frame->linesize[0]; } else if ((line_packets & 0xC000) == 0x4000) { av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); } else if ((line_packets & 0xC000) == 0x8000) { // "last byte" opcode pixel_ptr= y_ptr + s->frame->linesize[0] - 1; CHECK_PIXEL_PTR(0); pixels[pixel_ptr] = line_packets & 0xff; } else { compressed_lines--; pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); palette_idx2 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx2; } } else { CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } } y_ptr += s->frame->linesize[0]; } } break; case FLI_LC: /* line compressed */ starting_line = bytestream2_get_le16(&g2); y_ptr = 0; y_ptr += starting_line * s->frame->linesize[0]; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; line_packets = bytestream2_get_byte(&g2); if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2),8); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } else if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = palette_idx1; } } } } y_ptr += s->frame->linesize[0]; compressed_lines--; } break; case FLI_BLACK: /* set the whole frame to color 0 (which is usually black) */ memset(pixels, 0, s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: /* Byte run compression: This chunk type only occurs in the first * FLI frame and it will update the entire frame. */ y_ptr = 0; for (lines = 0; lines < s->avctx->height; lines++) { pixel_ptr = y_ptr; /* disregard the line packets; instead, iterate through all * pixels on a row */ bytestream2_skip(&g2, 1); pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (!byte_run) { av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n"); return AVERROR_INVALIDDATA; } if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } } y_ptr += s->frame->linesize[0]; } break; case FLI_COPY: /* copy the chunk (uncompressed frame) */ if (chunk_size - 6 > s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ "bigger than image, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; y_ptr += s->frame->linesize[0]) { bytestream2_get_buffer(&g2, &pixels[y_ptr], s->avctx->width); } } break; case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ bytestream2_skip(&g2, chunk_size - 6); break; default: av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); break; } frame_size -= chunk_size; num_chunks--; } /* by the end of the chunk, the stream ptr should equal the frame * size (minus 1, possibly); if it doesn't, issue a warning */ if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1)) av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, buf_size - bytestream2_get_bytes_left(&g2)); /* make the palette available on the way out */ memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); if (s->new_palette) { s->frame->palette_has_changed = 1; s->new_palette = 0; } if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; return buf_size; }
static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *src = avpkt->data; int buf_size = avpkt->size; PCMBRDecode *s = avctx->priv_data; GetByteContext gb; int num_source_channels, channel, retval; int sample_size, samples; int16_t *dst16; int32_t *dst32; if (buf_size < 4) { av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); return -1; } if (pcm_bluray_parse_header(avctx, src)) return -1; src += 4; buf_size -= 4; bytestream2_init(&gb, src, buf_size); /* There's always an even number of channels in the source */ num_source_channels = FFALIGN(avctx->channels, 2); sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; samples = buf_size / sample_size; /* get output buffer */ s->frame.nb_samples = samples; if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return retval; } dst16 = (int16_t *)s->frame.data[0]; dst32 = (int32_t *)s->frame.data[0]; if (samples) { switch (avctx->channel_layout) { /* cases with same number of source and coded channels */ case AV_CH_LAYOUT_STEREO: case AV_CH_LAYOUT_4POINT0: case AV_CH_LAYOUT_2_2: samples *= num_source_channels; if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { #if HAVE_BIGENDIAN bytestream2_get_buffer(&gb, dst16, buf_size); #else do { *dst16++ = bytestream2_get_be16u(&gb); } while (--samples); #endif } else { do { *dst32++ = bytestream2_get_be24u(&gb) << 8; } while (--samples); } break; /* cases where number of source channels = coded channels + 1 */ case AV_CH_LAYOUT_MONO: case AV_CH_LAYOUT_SURROUND: case AV_CH_LAYOUT_2_1: case AV_CH_LAYOUT_5POINT0: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { #if HAVE_BIGENDIAN bytestream2_get_buffer(&gb, dst16, avctx->channels * 2); dst16 += avctx->channels; #else channel = avctx->channels; do { *dst16++ = bytestream2_get_be16u(&gb); } while (--channel); #endif bytestream2_skip(&gb, 2); } while (--samples); } else { do { channel = avctx->channels; do { *dst32++ = bytestream2_get_be24u(&gb) << 8; } while (--channel); bytestream2_skip(&gb, 3); } while (--samples); } break; /* remapping: L, R, C, LBack, RBack, LF */ case AV_CH_LAYOUT_5POINT1: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16 += 6; } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32 += 6; } while (--samples); } break; /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */ case AV_CH_LAYOUT_7POINT0: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[6] = bytestream2_get_be16u(&gb); dst16 += 7; bytestream2_skip(&gb, 2); } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[6] = bytestream2_get_be24u(&gb) << 8; dst32 += 7; bytestream2_skip(&gb, 3); } while (--samples); } break; /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ case AV_CH_LAYOUT_7POINT1: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[6] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[7] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16 += 8; } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[6] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[7] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32 += 8; } while (--samples); } break; } } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; retval = bytestream2_tell(&gb); if (avctx->debug & FF_DEBUG_BITSTREAM) av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", retval, buf_size); return retval + 4; }
static int bethsoftvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { BethsoftvidContext * vid = avctx->priv_data; char block_type; uint8_t * dst; uint8_t * frame_end; int remaining = avctx->width; // number of bytes remaining on a line int wrap_to_next_line; int code, ret; int yoffset; if ((ret = ff_reget_buffer(avctx, vid->frame)) < 0) return ret; wrap_to_next_line = vid->frame->linesize[0] - avctx->width; if (avpkt->side_data_elems > 0 && avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) { bytestream2_init(&vid->g, avpkt->side_data[0].data, avpkt->side_data[0].size); if ((ret = set_palette(vid)) < 0) return ret; } bytestream2_init(&vid->g, avpkt->data, avpkt->size); dst = vid->frame->data[0]; frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height; switch(block_type = bytestream2_get_byte(&vid->g)){ case PALETTE_BLOCK: { *got_frame = 0; if ((ret = set_palette(vid)) < 0) { av_log(avctx, AV_LOG_ERROR, "error reading palette\n"); return ret; } return bytestream2_tell(&vid->g); } case VIDEO_YOFF_P_FRAME: yoffset = bytestream2_get_le16(&vid->g); if(yoffset >= avctx->height) return AVERROR_INVALIDDATA; dst += vid->frame->linesize[0] * yoffset; } // main code while((code = bytestream2_get_byte(&vid->g))){ int length = code & 0x7f; // copy any bytes starting at the current position, and ending at the frame width while(length > remaining){ if(code < 0x80) bytestream2_get_buffer(&vid->g, dst, remaining); else if(block_type == VIDEO_I_FRAME) memset(dst, bytestream2_peek_byte(&vid->g), remaining); length -= remaining; // decrement the number of bytes to be copied dst += remaining + wrap_to_next_line; // skip over extra bytes at end of frame remaining = avctx->width; if(dst == frame_end) goto end; } // copy any remaining bytes after / if line overflows if(code < 0x80) bytestream2_get_buffer(&vid->g, dst, length); else if(block_type == VIDEO_I_FRAME) memset(dst, bytestream2_get_byte(&vid->g), length); remaining -= length; dst += length; } end: if ((ret = av_frame_ref(data, vid->frame)) < 0) return ret; *got_frame = 1; return avpkt->size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = &c93->pictures[c93->currentpic]; AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; AVFrame *picture = data; GetByteContext gb; uint8_t *out; int stride, i, x, y, b, bt = 0; c93->currentpic ^= 1; newpic->reference = 3; newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, newpic)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } stride = newpic->linesize[0]; bytestream2_init(&gb, buf, buf_size); b = bytestream2_get_byte(&gb); if (b & C93_FIRST_FRAME) { newpic->pict_type = AV_PICTURE_TYPE_I; newpic->key_frame = 1; } else { newpic->pict_type = AV_PICTURE_TYPE_P; newpic->key_frame = 0; } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = bytestream2_get_byte(&gb); block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream2_get_le16(&gb); if (copy_block(avctx, out, copy_from, offset, 8, stride)) return -1; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { offset = bytestream2_get_le16(&gb); if (copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) return -1; } } break; case C93_8X8_2COLOR: bytestream2_get_buffer(&gb, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, bytestream2_get_byte(&gb)); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream2_get_buffer(&gb, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream2_get_le16(&gb)); } else if (block_type == C93_4X4_4COLOR) { bytestream2_get_buffer(&gb, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream2_get_le32(&gb)); } else { bytestream2_get_buffer(&gb, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream2_get_le16(&gb)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream2_get_buffer(&gb, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return -1; } bt >>= 4; out += 8; } } if (b & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; for (i = 0; i < 256; i++) { palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb); } } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } *picture = *newpic; *data_size = sizeof(AVFrame); return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = c93->pictures[c93->currentpic]; AVFrame * const oldpic = c93->pictures[c93->currentpic^1]; GetByteContext gb; uint8_t *out; int stride, ret, i, x, y, b, bt = 0; if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0) return ret; c93->currentpic ^= 1; if ((ret = ff_reget_buffer(avctx, newpic)) < 0) return ret; stride = newpic->linesize[0]; bytestream2_init(&gb, buf, buf_size); b = bytestream2_get_byte(&gb); if (b & C93_FIRST_FRAME) { newpic->pict_type = AV_PICTURE_TYPE_I; newpic->key_frame = 1; } else { newpic->pict_type = AV_PICTURE_TYPE_P; newpic->key_frame = 0; } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = bytestream2_get_byte(&gb); block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream2_get_le16(&gb); if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0) return ret; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { int offset = bytestream2_get_le16(&gb); int from_x = offset % WIDTH; int from_y = offset / WIDTH; if (block_type == C93_4X4_FROM_CURR && from_y == y+j && (FFABS(from_x - x-i) < 4 || FFABS(from_x - x-i) > WIDTH-4)) { avpriv_request_sample(avctx, "block overlap %d %d %d %d\n", from_x, x+i, from_y, y+j); return AVERROR_INVALIDDATA; } if ((ret = copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) < 0) return ret; } } break; case C93_8X8_2COLOR: bytestream2_get_buffer(&gb, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, bytestream2_get_byte(&gb)); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream2_get_buffer(&gb, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream2_get_le16(&gb)); } else if (block_type == C93_4X4_4COLOR) { bytestream2_get_buffer(&gb, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream2_get_le32(&gb)); } else { bytestream2_get_buffer(&gb, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream2_get_le16(&gb)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream2_get_buffer(&gb, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return AVERROR_INVALIDDATA; } bt >>= 4; out += 8; } } if (b & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; for (i = 0; i < 256; i++) { palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb); } newpic->palette_has_changed = 1; } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } if ((ret = av_frame_ref(data, newpic)) < 0) return ret; *got_frame = 1; return buf_size; }
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { FlicDecodeContext *s = avctx->priv_data; GetByteContext g2; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; unsigned char palette_idx2; unsigned int frame_size; int num_chunks; unsigned int chunk_size; int chunk_type; int i, j; int color_packets; int color_changes; int color_shift; unsigned char r, g, b; int lines; int compressed_lines; int starting_line; signed short line_packets; int y_ptr; int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; unsigned int pixel_limit; bytestream2_init(&g2, buf, buf_size); s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } pixels = s->frame.data[0]; pixel_limit = s->avctx->height * s->frame.linesize[0]; if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) return AVERROR_INVALIDDATA; frame_size = bytestream2_get_le32(&g2); if (frame_size > buf_size) frame_size = buf_size; bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ frame_size -= 16; /* iterate through the chunks */ while ((frame_size >= 6) && (num_chunks > 0)) { int stream_ptr_after_chunk; chunk_size = bytestream2_get_le32(&g2); if (chunk_size > frame_size) { av_log(avctx, AV_LOG_WARNING, "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size); chunk_size = frame_size; } stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size; chunk_type = bytestream2_get_le16(&g2); switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during * initialization) */ if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) color_shift = 0; else color_shift = 2; /* set up the palette */ color_packets = bytestream2_get_le16(&g2); palette_ptr = 0; for (i = 0; i < color_packets; i++) { /* first byte is how many colors to skip */ palette_ptr += bytestream2_get_byte(&g2); /* next byte indicates how many entries to change */ color_changes = bytestream2_get_byte(&g2); /* if there are 0 color changes, there are actually 256 */ if (color_changes == 0) color_changes = 256; if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk) break; for (j = 0; j < color_changes; j++) { unsigned int entry; /* wrap around, for good measure */ if ((unsigned)palette_ptr >= 256) palette_ptr = 0; r = bytestream2_get_byte(&g2) << color_shift; g = bytestream2_get_byte(&g2) << color_shift; b = bytestream2_get_byte(&g2) << color_shift; entry = 0xFF << 24 | r << 16 | g << 8 | b; if (color_shift == 2) entry |= entry >> 6 & 0x30303; if (s->palette[palette_ptr] != entry) s->new_palette = 1; s->palette[palette_ptr++] = entry; } } break; case FLI_DELTA: y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) break; line_packets = bytestream2_get_le16(&g2); if ((line_packets & 0xC000) == 0xC000) { // line skip opcode line_packets = -line_packets; y_ptr += line_packets * s->frame.linesize[0]; } else if ((line_packets & 0xC000) == 0x4000) { av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); } else if ((line_packets & 0xC000) == 0x8000) { // "last byte" opcode pixel_ptr= y_ptr + s->frame.linesize[0] - 1; CHECK_PIXEL_PTR(0); pixels[pixel_ptr] = line_packets & 0xff; } else { compressed_lines--; pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) break; /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); palette_idx2 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx2; } } else { CHECK_PIXEL_PTR(byte_run * 2); if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk) break; for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } } y_ptr += s->frame.linesize[0]; } } break; case FLI_LC: /* line compressed */ starting_line = bytestream2_get_le16(&g2); y_ptr = 0; y_ptr += starting_line * s->frame.linesize[0]; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) break; line_packets = bytestream2_get_byte(&g2); if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) break; pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2),8); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk) break; for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } else if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = palette_idx1; } } } } y_ptr += s->frame.linesize[0]; compressed_lines--; } break; case FLI_BLACK: /* set the whole frame to color 0 (which is usually black) */ memset(pixels, 0, s->frame.linesize[0] * s->avctx->height); break; case FLI_BRUN: /* Byte run compression: This chunk type only occurs in the first * FLI frame and it will update the entire frame. */ y_ptr = 0; for (lines = 0; lines < s->avctx->height; lines++) { pixel_ptr = y_ptr; /* disregard the line packets; instead, iterate through all * pixels on a row */ bytestream2_skip(&g2, 1); pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) break; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk) break; for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } } y_ptr += s->frame.linesize[0]; } break; case FLI_COPY: /* copy the chunk (uncompressed frame) */ if (chunk_size - 6 != s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ "has incorrect size, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; y_ptr += s->frame.linesize[0]) { bytestream2_get_buffer(&g2, &pixels[y_ptr], s->avctx->width); } } break; case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ break; default: av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); break; } if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0) bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2)); frame_size -= chunk_size; num_chunks--; } /* by the end of the chunk, the stream ptr should equal the frame * size (minus 1 or 2, possibly); if it doesn't, issue a warning */ if (bytestream2_get_bytes_left(&g2) > 2) av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, buf_size - bytestream2_get_bytes_left(&g2)); /* make the palette available on the way out */ memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); if (s->new_palette) { s->frame.palette_has_changed = 1; s->new_palette = 0; } *data_size=sizeof(AVFrame); *(AVFrame*)data = s->frame; return buf_size; }
static int gif_read_image(GifState *s, AVFrame *frame) { int left, top, width, height, bits_per_pixel, code_size, flags; int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; uint8_t *ptr, *spal, *palette, *ptr1; left = bytestream2_get_le16(&s->gb); top = bytestream2_get_le16(&s->gb); width = bytestream2_get_le16(&s->gb); height = bytestream2_get_le16(&s->gb); flags = bytestream2_get_byte(&s->gb); is_interleaved = flags & 0x40; has_local_palette = flags & 0x80; bits_per_pixel = (flags & 0x07) + 1; av_dlog(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); if (has_local_palette) { bytestream2_get_buffer(&s->gb, s->local_palette, 3 * (1 << bits_per_pixel)); palette = s->local_palette; } else { palette = s->global_palette; bits_per_pixel = s->bits_per_pixel; } /* verify that all the image is inside the screen dimensions */ if (left + width > s->screen_width || top + height > s->screen_height || !width || !height) { av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n"); return AVERROR_INVALIDDATA; } /* build the palette */ n = (1 << bits_per_pixel); spal = palette; for(i = 0; i < n; i++) { s->image_palette[i] = (0xffu << 24) | AV_RB24(spal); spal += 3; } for(; i < 256; i++) s->image_palette[i] = (0xffu << 24); /* handle transparency */ if (s->transparent_color_index >= 0) s->image_palette[s->transparent_color_index] = 0; /* now get the image data */ code_size = bytestream2_get_byte(&s->gb); ff_lzw_decode_init(s->lzw, code_size, s->gb.buffer, bytestream2_get_bytes_left(&s->gb), FF_LZW_GIF); /* read all the image */ linesize = frame->linesize[0]; ptr1 = frame->data[0] + top * linesize + left; ptr = ptr1; pass = 0; y1 = 0; for (y = 0; y < height; y++) { ff_lzw_decode(s->lzw, ptr, width); if (is_interleaved) { switch(pass) { default: case 0: case 1: y1 += 8; ptr += linesize * 8; if (y1 >= height) { y1 = pass ? 2 : 4; ptr = ptr1 + linesize * y1; pass++; } break; case 2: y1 += 4; ptr += linesize * 4; if (y1 >= height) { y1 = 1; ptr = ptr1 + linesize; pass++; } break; case 3: y1 += 2; ptr += linesize * 2; break; } } else { ptr += linesize; } } /* read the garbage data until end marker is found */ ff_lzw_decode_tail(s->lzw); bytestream2_skip(&s->gb, ff_lzw_size_read(s->lzw)); return 0; }