static int gif_read_extension(GifState *s) { int ext_code, ext_len, gce_flags, gce_transparent_index; /* There must be at least 2 bytes: * 1 for extension label and 1 for extension length. */ if (bytestream2_get_bytes_left(&s->gb) < 2) return AVERROR_INVALIDDATA; ext_code = bytestream2_get_byteu(&s->gb); ext_len = bytestream2_get_byteu(&s->gb); av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len); switch(ext_code) { case GIF_GCE_EXT_LABEL: if (ext_len != 4) goto discard_ext; /* We need at least 5 bytes more: 4 is for extension body * and 1 for next block size. */ if (bytestream2_get_bytes_left(&s->gb) < 5) return AVERROR_INVALIDDATA; gce_flags = bytestream2_get_byteu(&s->gb); bytestream2_skipu(&s->gb, 2); // delay during which the frame is shown gce_transparent_index = bytestream2_get_byteu(&s->gb); if (gce_flags & 0x01) s->transparent_color_index = gce_transparent_index; else s->transparent_color_index = -1; s->gce_disposal = (gce_flags >> 2) & 0x7; av_dlog(s->avctx, "gce_flags=%x tcolor=%d disposal=%d\n", gce_flags, s->transparent_color_index, s->gce_disposal); if (s->gce_disposal > 3) { s->gce_disposal = GCE_DISPOSAL_NONE; av_dlog(s->avctx, "invalid value in gce_disposal (%d). Using default value of 0.\n", ext_len); } ext_len = bytestream2_get_byteu(&s->gb); break; } /* NOTE: many extension blocks can come after */ discard_ext: while (ext_len) { /* There must be at least ext_len bytes and 1 for next block size byte. */ if (bytestream2_get_bytes_left(&s->gb) < ext_len + 1) return AVERROR_INVALIDDATA; bytestream2_skipu(&s->gb, ext_len); ext_len = bytestream2_get_byteu(&s->gb); av_dlog(s->avctx, "ext_len1=%d\n", ext_len); } return 0; }
static av_cold int decode_init(AVCodecContext *avctx) { AnmContext *s = avctx->priv_data; int i; avctx->pix_fmt = PIX_FMT_PAL8; s->frame.reference = 1; bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size); if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256) return -1; bytestream2_skipu(&s->gb, 16 * 8); for (i = 0; i < 256; i++) s->palette[i] = bytestream2_get_le32u(&s->gb); return 0; }
static av_cold int decode_init(AVCodecContext *avctx) { AnmContext *s = avctx->priv_data; int i; avctx->pix_fmt = AV_PIX_FMT_PAL8; s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size); if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256) return AVERROR_INVALIDDATA; bytestream2_skipu(&s->gb, 16 * 8); for (i = 0; i < 256; i++) s->palette[i] = bytestream2_get_le32u(&s->gb); return 0; }
static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { GetByteContext gb; AVFrame * const p = data; int compressed, xmin, ymin, xmax, ymax, ret; unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; uint8_t *ptr, *scanline; if (avpkt->size < 128) return AVERROR_INVALIDDATA; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_byteu(&gb) != 0x0a || bytestream2_get_byteu(&gb) > 5) { av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n"); return AVERROR_INVALIDDATA; } compressed = bytestream2_get_byteu(&gb); bits_per_pixel = bytestream2_get_byteu(&gb); xmin = bytestream2_get_le16u(&gb); ymin = bytestream2_get_le16u(&gb); xmax = bytestream2_get_le16u(&gb); ymax = bytestream2_get_le16u(&gb); avctx->sample_aspect_ratio.num = bytestream2_get_le16u(&gb); avctx->sample_aspect_ratio.den = bytestream2_get_le16u(&gb); if (xmax < xmin || ymax < ymin) { av_log(avctx, AV_LOG_ERROR, "invalid image dimensions\n"); return AVERROR_INVALIDDATA; } w = xmax - xmin + 1; h = ymax - ymin + 1; bytestream2_skipu(&gb, 49); nplanes = bytestream2_get_byteu(&gb); bytes_per_line = bytestream2_get_le16u(&gb); bytes_per_scanline = nplanes * bytes_per_line; if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return AVERROR_INVALIDDATA; } switch ((nplanes<<8) + bits_per_pixel) { case 0x0308: avctx->pix_fmt = AV_PIX_FMT_RGB24; break; case 0x0108: case 0x0104: case 0x0102: case 0x0101: case 0x0401: case 0x0301: case 0x0201: avctx->pix_fmt = AV_PIX_FMT_PAL8; break; default: av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); return AVERROR_INVALIDDATA; } bytestream2_skipu(&gb, 60); if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type = AV_PICTURE_TYPE_I; ptr = p->data[0]; stride = p->linesize[0]; scanline = av_malloc(bytes_per_scanline + FF_INPUT_BUFFER_PADDING_SIZE); if (!scanline) return AVERROR(ENOMEM); if (nplanes == 3 && bits_per_pixel == 8) { for (y=0; y<h; y++) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { ptr[3*x ] = scanline[x ]; ptr[3*x+1] = scanline[x+ bytes_per_line ]; ptr[3*x+2] = scanline[x+(bytes_per_line<<1)]; } ptr += stride; } } else if (nplanes == 1 && bits_per_pixel == 8) { int palstart = avpkt->size - 769; for (y=0; y<h; y++, ptr+=stride) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } if (bytestream2_tell(&gb) != palstart) { av_log(avctx, AV_LOG_WARNING, "image data possibly corrupted\n"); bytestream2_seek(&gb, palstart, SEEK_SET); } if (bytestream2_get_byte(&gb) != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); ret = AVERROR_INVALIDDATA; goto end; } } else if (nplanes == 1) { /* all packed formats, max. 16 colors */ GetBitContext s; for (y=0; y<h; y++) { init_get_bits8(&s, scanline, bytes_per_scanline); pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) ptr[x] = get_bits(&s, bits_per_pixel); ptr += stride; } } else { /* planar, 4, 8 or 16 colors */ int i; for (y=0; y<h; y++) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { int m = 0x80 >> (x&7), v = 0; for (i=nplanes - 1; i>=0; i--) { v <<= 1; v += !!(scanline[i*bytes_per_line + (x>>3)] & m); } ptr[x] = v; } ptr += stride; } } ret = bytestream2_tell(&gb); if (nplanes == 1 && bits_per_pixel == 8) { pcx_palette(&gb, (uint32_t *) p->data[1], 256); ret += 256 * 3; } else if (bits_per_pixel * nplanes == 1) { AV_WN32A(p->data[1] , 0xFF000000); AV_WN32A(p->data[1]+4, 0xFFFFFFFF); } else if (bits_per_pixel < 8) { bytestream2_seek(&gb, 16, SEEK_SET); pcx_palette(&gb, (uint32_t *) p->data[1], 16); } *got_frame = 1; end: av_free(scanline); return ret; }
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { int buf_size = avpkt->size; DPCMContext *s = avctx->priv_data; int out = 0, ret; int predictor[2]; int ch = 0; int stereo = s->channels - 1; int16_t *output_samples, *samples_end; GetByteContext gb; if (stereo && (buf_size & 1)) buf_size--; bytestream2_init(&gb, avpkt->data, buf_size); /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: out = buf_size - 8; break; case CODEC_ID_INTERPLAY_DPCM: out = buf_size - 6 - s->channels; break; case CODEC_ID_XAN_DPCM: out = buf_size - 2 * s->channels; break; case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) out = buf_size * 2; else out = buf_size; break; } if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } /* get output buffer */ s->frame.nb_samples = out / s->channels; if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } output_samples = (int16_t *)s->frame.data[0]; samples_end = output_samples + out; switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: bytestream2_skipu(&gb, 6); if (stereo) { predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16); predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16); } else { predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16); } /* decode the samples */ while (output_samples < samples_end) { predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_INTERPLAY_DPCM: bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */ for (ch = 0; ch < s->channels; ch++) { predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); *output_samples++ = predictor[ch]; } ch = 0; while (output_samples < samples_end) { predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; case CODEC_ID_XAN_DPCM: { int shift[2] = { 4, 4 }; for (ch = 0; ch < s->channels; ch++) predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); ch = 0; while (output_samples < samples_end) { int diff = bytestream2_get_byteu(&gb); int n = diff & 3; if (n == 3) shift[ch]++; else shift[ch] -= (2 * n); diff = sign_extend((diff &~ 3) << 8, 16); /* saturate the shifter to a lower limit of 0 */ if (shift[ch] < 0) shift[ch] = 0; diff >>= shift[ch]; predictor[ch] += diff; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } break; } case CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) { uint8_t *output_samples_u8 = s->frame.data[0], *samples_end_u8 = output_samples_u8 + out; while (output_samples_u8 < samples_end_u8) { int n = bytestream2_get_byteu(&gb); s->sample[0] += s->sol_table[n >> 4]; s->sample[0] = av_clip_uint8(s->sample[0]); *output_samples_u8++ = s->sample[0]; s->sample[stereo] += s->sol_table[n & 0x0F]; s->sample[stereo] = av_clip_uint8(s->sample[stereo]); *output_samples_u8++ = s->sample[stereo]; } } else { while (output_samples < samples_end) {
static int brpix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { BRPixContext *s = avctx->priv_data; AVFrame *frame_out = data; int ret; GetByteContext gb; unsigned int bytes_pp; unsigned int magic[4]; unsigned int chunk_type; unsigned int data_len; BRPixHeader hdr; bytestream2_init(&gb, avpkt->data, avpkt->size); magic[0] = bytestream2_get_be32(&gb); magic[1] = bytestream2_get_be32(&gb); magic[2] = bytestream2_get_be32(&gb); magic[3] = bytestream2_get_be32(&gb); if (magic[0] != 0x12 || magic[1] != 0x8 || magic[2] != 0x2 || magic[3] != 0x2) { av_log(avctx, AV_LOG_ERROR, "Not a BRender PIX file\n"); return AVERROR_INVALIDDATA; } chunk_type = bytestream2_get_be32(&gb); if (chunk_type != 0x3 && chunk_type != 0x3d) { av_log(avctx, AV_LOG_ERROR, "Invalid chunk type %d\n", chunk_type); return AVERROR_INVALIDDATA; } ret = brpix_decode_header(&hdr, &gb); if (!ret) { av_log(avctx, AV_LOG_ERROR, "Invalid header length\n"); return AVERROR_INVALIDDATA; } switch (hdr.format) { case 3: avctx->pix_fmt = AV_PIX_FMT_PAL8; bytes_pp = 1; break; case 4: avctx->pix_fmt = AV_PIX_FMT_RGB555BE; bytes_pp = 2; break; case 5: avctx->pix_fmt = AV_PIX_FMT_RGB565BE; bytes_pp = 2; break; case 6: avctx->pix_fmt = AV_PIX_FMT_RGB24; bytes_pp = 3; break; case 7: avctx->pix_fmt = AV_PIX_FMT_0RGB; bytes_pp = 4; break; case 18: avctx->pix_fmt = AV_PIX_FMT_GRAY8A; bytes_pp = 2; break; default: av_log(avctx, AV_LOG_ERROR, "Format %d is not supported\n", hdr.format); return AVERROR_PATCHWELCOME; } if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); if (av_image_check_size(hdr.width, hdr.height, 0, avctx) < 0) return AVERROR_INVALIDDATA; if (hdr.width != avctx->width || hdr.height != avctx->height) avcodec_set_dimensions(avctx, hdr.width, hdr.height); if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } chunk_type = bytestream2_get_be32(&gb); if (avctx->pix_fmt == AV_PIX_FMT_PAL8 && (chunk_type == 0x3 || chunk_type == 0x3d)) { BRPixHeader palhdr; uint32_t *pal_out = (uint32_t *)s->frame.data[1]; int i; ret = brpix_decode_header(&palhdr, &gb); if (!ret) { av_log(avctx, AV_LOG_ERROR, "Invalid palette header length\n"); return AVERROR_INVALIDDATA; } if (palhdr.format != 7) { av_log(avctx, AV_LOG_ERROR, "Palette is not in 0RGB format\n"); return AVERROR_INVALIDDATA; } chunk_type = bytestream2_get_be32(&gb); data_len = bytestream2_get_be32(&gb); bytestream2_skip(&gb, 8); if (chunk_type != 0x21 || data_len != 1032 || bytestream2_get_bytes_left(&gb) < 1032) { av_log(avctx, AV_LOG_ERROR, "Invalid palette data\n"); return AVERROR_INVALIDDATA; } // convert 0RGB to machine endian format (ARGB32) for (i = 0; i < 256; ++i) { bytestream2_skipu(&gb, 1); *pal_out++ = (0xFFU << 24) | bytestream2_get_be24u(&gb); } bytestream2_skip(&gb, 8); s->frame.palette_has_changed = 1; chunk_type = bytestream2_get_be32(&gb); } data_len = bytestream2_get_be32(&gb); bytestream2_skip(&gb, 8); // read the image data to the buffer { unsigned int bytes_per_scanline = bytes_pp * hdr.width; unsigned int bytes_left = bytestream2_get_bytes_left(&gb); if (chunk_type != 0x21 || data_len != bytes_left || bytes_left / bytes_per_scanline < hdr.height) { av_log(avctx, AV_LOG_ERROR, "Invalid image data\n"); return AVERROR_INVALIDDATA; } av_image_copy_plane(s->frame.data[0], s->frame.linesize[0], avpkt->data + bytestream2_tell(&gb), bytes_per_scanline, bytes_per_scanline, hdr.height); } *frame_out = s->frame; *got_frame = 1; return avpkt->size; }
static int xwd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame *p = data; const uint8_t *buf = avpkt->data; int i, ret, buf_size = avpkt->size; uint32_t version, header_size, vclass, ncolors; uint32_t xoffset, be, bpp, lsize, rsize; uint32_t pixformat, pixdepth, bunit, bitorder, bpad; uint32_t rgb[3]; uint8_t *ptr; GetByteContext gb; if (buf_size < XWD_HEADER_SIZE) return AVERROR_INVALIDDATA; bytestream2_init(&gb, buf, buf_size); header_size = bytestream2_get_be32u(&gb); version = bytestream2_get_be32u(&gb); if (version != XWD_VERSION) { av_log(avctx, AV_LOG_ERROR, "unsupported version\n"); return AVERROR_INVALIDDATA; } if (buf_size < header_size || header_size < XWD_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "invalid header size\n"); return AVERROR_INVALIDDATA; } pixformat = bytestream2_get_be32u(&gb); pixdepth = bytestream2_get_be32u(&gb); avctx->width = bytestream2_get_be32u(&gb); avctx->height = bytestream2_get_be32u(&gb); xoffset = bytestream2_get_be32u(&gb); be = bytestream2_get_be32u(&gb); bunit = bytestream2_get_be32u(&gb); bitorder = bytestream2_get_be32u(&gb); bpad = bytestream2_get_be32u(&gb); bpp = bytestream2_get_be32u(&gb); lsize = bytestream2_get_be32u(&gb); vclass = bytestream2_get_be32u(&gb); rgb[0] = bytestream2_get_be32u(&gb); rgb[1] = bytestream2_get_be32u(&gb); rgb[2] = bytestream2_get_be32u(&gb); bytestream2_skipu(&gb, 8); ncolors = bytestream2_get_be32u(&gb); bytestream2_skipu(&gb, header_size - (XWD_HEADER_SIZE - 20)); av_log(avctx, AV_LOG_DEBUG, "pixformat %"PRIu32", pixdepth %"PRIu32", bunit %"PRIu32", bitorder %"PRIu32", bpad %"PRIu32"\n", pixformat, pixdepth, bunit, bitorder, bpad); av_log(avctx, AV_LOG_DEBUG, "vclass %"PRIu32", ncolors %"PRIu32", bpp %"PRIu32", be %"PRIu32", lsize %"PRIu32", xoffset %"PRIu32"\n", vclass, ncolors, bpp, be, lsize, xoffset); av_log(avctx, AV_LOG_DEBUG, "red %0"PRIx32", green %0"PRIx32", blue %0"PRIx32"\n", rgb[0], rgb[1], rgb[2]); if (pixformat > XWD_Z_PIXMAP) { av_log(avctx, AV_LOG_ERROR, "invalid pixmap format\n"); return AVERROR_INVALIDDATA; } if (pixdepth == 0 || pixdepth > 32) { av_log(avctx, AV_LOG_ERROR, "invalid pixmap depth\n"); return AVERROR_INVALIDDATA; } if (xoffset) { avpriv_request_sample(avctx, "xoffset %"PRIu32"", xoffset); return AVERROR_PATCHWELCOME; } if (be > 1) { av_log(avctx, AV_LOG_ERROR, "invalid byte order\n"); return AVERROR_INVALIDDATA; } if (bitorder > 1) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap bit order\n"); return AVERROR_INVALIDDATA; } if (bunit != 8 && bunit != 16 && bunit != 32) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap unit\n"); return AVERROR_INVALIDDATA; } if (bpad != 8 && bpad != 16 && bpad != 32) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap scan-line pad\n"); return AVERROR_INVALIDDATA; } if (bpp == 0 || bpp > 32) { av_log(avctx, AV_LOG_ERROR, "invalid bits per pixel\n"); return AVERROR_INVALIDDATA; } if (ncolors > 256) { av_log(avctx, AV_LOG_ERROR, "invalid number of entries in colormap\n"); return AVERROR_INVALIDDATA; } if ((ret = av_image_check_size(avctx->width, avctx->height, 0, NULL)) < 0) return ret; rsize = FFALIGN(avctx->width * bpp, bpad) / 8; if (lsize < rsize) { av_log(avctx, AV_LOG_ERROR, "invalid bytes per scan-line\n"); return AVERROR_INVALIDDATA; } if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + (uint64_t)avctx->height * lsize) { av_log(avctx, AV_LOG_ERROR, "input buffer too small\n"); return AVERROR_INVALIDDATA; } if (pixformat != XWD_Z_PIXMAP) { avpriv_report_missing_feature(avctx, "Pixmap format %"PRIu32, pixformat); return AVERROR_PATCHWELCOME; } avctx->pix_fmt = AV_PIX_FMT_NONE; switch (vclass) { case XWD_STATIC_GRAY: case XWD_GRAY_SCALE: if (bpp != 1 && bpp != 8) return AVERROR_INVALIDDATA; if (bpp == 1 && pixdepth == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; } else if (bpp == 8 && pixdepth == 8) { avctx->pix_fmt = AV_PIX_FMT_GRAY8; } break; case XWD_STATIC_COLOR: case XWD_PSEUDO_COLOR: if (bpp == 8) avctx->pix_fmt = AV_PIX_FMT_PAL8; break; case XWD_TRUE_COLOR: case XWD_DIRECT_COLOR: if (bpp != 16 && bpp != 24 && bpp != 32) return AVERROR_INVALIDDATA; if (bpp == 16 && pixdepth == 15) { if (rgb[0] == 0x7C00 && rgb[1] == 0x3E0 && rgb[2] == 0x1F) avctx->pix_fmt = be ? AV_PIX_FMT_RGB555BE : AV_PIX_FMT_RGB555LE; else if (rgb[0] == 0x1F && rgb[1] == 0x3E0 && rgb[2] == 0x7C00) avctx->pix_fmt = be ? AV_PIX_FMT_BGR555BE : AV_PIX_FMT_BGR555LE; } else if (bpp == 16 && pixdepth == 16) { if (rgb[0] == 0xF800 && rgb[1] == 0x7E0 && rgb[2] == 0x1F) avctx->pix_fmt = be ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_RGB565LE; else if (rgb[0] == 0x1F && rgb[1] == 0x7E0 && rgb[2] == 0xF800) avctx->pix_fmt = be ? AV_PIX_FMT_BGR565BE : AV_PIX_FMT_BGR565LE; } else if (bpp == 24) { if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF) avctx->pix_fmt = be ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24; else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000) avctx->pix_fmt = be ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24; } else if (bpp == 32) { if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF) avctx->pix_fmt = be ? AV_PIX_FMT_ARGB : AV_PIX_FMT_BGRA; else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000) avctx->pix_fmt = be ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA; } bytestream2_skipu(&gb, ncolors * XWD_CMAP_SIZE); break; default: av_log(avctx, AV_LOG_ERROR, "invalid visual class\n"); return AVERROR_INVALIDDATA; } if (avctx->pix_fmt == AV_PIX_FMT_NONE) { avpriv_request_sample(avctx, "Unknown file: bpp %"PRIu32", pixdepth %"PRIu32", vclass %"PRIu32"", bpp, pixdepth, vclass); return AVERROR_PATCHWELCOME; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; p->key_frame = 1; p->pict_type = AV_PICTURE_TYPE_I; if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { uint32_t *dst = (uint32_t *)p->data[1]; uint8_t red, green, blue; for (i = 0; i < ncolors; i++) { bytestream2_skipu(&gb, 4); // skip colormap entry number red = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 1); green = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 1); blue = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 3); // skip bitmask flag and padding dst[i] = 0xFFU << 24 | red << 16 | green << 8 | blue; } } ptr = p->data[0]; for (i = 0; i < avctx->height; i++) { bytestream2_get_bufferu(&gb, ptr, rsize); bytestream2_skipu(&gb, lsize - rsize); ptr += p->linesize[0]; } *got_frame = 1; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame *f = data; GetByteContext gb; int width, height, ret, bits_pixel, pixel; uint8_t *out_buf; uint8_t count; int x, y; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&gb) < ALIAS_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "Header too small %d.\n", avpkt->size); return AVERROR_INVALIDDATA; } width = bytestream2_get_be16u(&gb); height = bytestream2_get_be16u(&gb); bytestream2_skipu(&gb, 4); // obsolete X, Y offset bits_pixel = bytestream2_get_be16u(&gb); if (bits_pixel == 24) avctx->pix_fmt = AV_PIX_FMT_BGR24; else if (bits_pixel == 8) avctx->pix_fmt = AV_PIX_FMT_GRAY8; else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n"); return AVERROR_INVALIDDATA; } ret = ff_set_dimensions(avctx, width, height); if (ret < 0) return ret; ret = ff_get_buffer(avctx, f, 0); if (ret < 0) return ret; f->pict_type = AV_PICTURE_TYPE_I; f->key_frame = 1; x = 0; y = 1; out_buf = f->data[0]; while (bytestream2_get_bytes_left(&gb) > 0) { int i; /* set buffer at the right position at every new line */ if (x == avctx->width) { x = 0; out_buf = f->data[0] + f->linesize[0] * y++; if (y > avctx->height) { av_log(avctx, AV_LOG_ERROR, "Ended frame decoding with %d bytes left.\n", bytestream2_get_bytes_left(&gb)); return AVERROR_INVALIDDATA; } } /* read packet and copy data */ count = bytestream2_get_byteu(&gb); if (!count || x + count > avctx->width) { av_log(avctx, AV_LOG_ERROR, "Invalid run length %d.\n", count); return AVERROR_INVALIDDATA; } if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { pixel = bytestream2_get_be24(&gb); for (i = 0; i < count; i++) { AV_WB24(out_buf, pixel); out_buf += 3; } } else { // AV_PIX_FMT_GRAY8 pixel = bytestream2_get_byte(&gb); for (i = 0; i < count; i++) *out_buf++ = pixel; } x += i; } if (x != width || y != height) { av_log(avctx, AV_LOG_ERROR, "Picture stopped at %d,%d.\n", x, y); return AVERROR_INVALIDDATA; } *got_frame = 1; return avpkt->size; }
static int redspark_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; RedSparkContext *redspark = s->priv_data; AVCodecParameters *par; GetByteContext gbc; int i, coef_off, ret = 0; uint32_t key, data; uint8_t header[HEADER_SIZE]; AVStream *st; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); par = st->codecpar; /* Decrypt header */ data = avio_rb32(pb); key = data ^ 0x52656453; data ^= key; AV_WB32(header, data); key = rol(key, 11); for (i = 4; i < HEADER_SIZE; i += 4) { key += rol(key, 3); data = avio_rb32(pb) ^ key; AV_WB32(header + i, data); } par->codec_id = AV_CODEC_ID_ADPCM_THP; par->codec_type = AVMEDIA_TYPE_AUDIO; bytestream2_init(&gbc, header, HEADER_SIZE); bytestream2_seek(&gbc, 0x3c, SEEK_SET); par->sample_rate = bytestream2_get_be32u(&gbc); if (par->sample_rate <= 0 || par->sample_rate > 96000) { av_log(s, AV_LOG_ERROR, "Invalid sample rate: %d\n", par->sample_rate); return AVERROR_INVALIDDATA; } st->duration = bytestream2_get_be32u(&gbc) * 14; redspark->samples_count = 0; bytestream2_skipu(&gbc, 10); par->channels = bytestream2_get_byteu(&gbc); if (!par->channels) { return AVERROR_INVALIDDATA; } coef_off = 0x54 + par->channels * 8; if (bytestream2_get_byteu(&gbc)) // Loop flag coef_off += 16; if (coef_off + par->channels * (32 + 14) > HEADER_SIZE) { return AVERROR_INVALIDDATA; } if (ff_alloc_extradata(par, 32 * par->channels)) { return AVERROR_INVALIDDATA; } /* Get the ADPCM table */ bytestream2_seek(&gbc, coef_off, SEEK_SET); for (i = 0; i < par->channels; i++) { if (bytestream2_get_bufferu(&gbc, par->extradata + i * 32, 32) != 32) { return AVERROR_INVALIDDATA; } bytestream2_skipu(&gbc, 14); } avpriv_set_pts_info(st, 64, 1, par->sample_rate); return ret; }